2017 山理校赛 线段树单点更新+状压

来源:互联网 发布:兴业银行淘宝网银支付 编辑:程序博客网 时间:2024/06/07 04:51

皮卡丘的梦想2
Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic
Problem Description

一天,一只住在 501 实验室的皮卡丘决定发奋学习,成为像 LeiQ 一样的巨巨,于是他向镇上的贤者金桔请教如何才能进化成一只雷丘。
金桔告诉他需要进化石才能进化,并给了他一个地图,地图上有 n 个小镇,他需要从这些小镇中收集进化石。
接下来他会进行 q 次操作,可能是打听进化石的信息,也可能是向你询问 l 到 r 之间的进化石种类。
如果是打听信息,则皮卡丘会得到一个小镇的进化石变化信息,可能是引入了新的进化石,也可能是失去了全部的某种进化石。
如果是向你询问,你需要回答他第 l 个小镇到第 r 个小镇之间的进化石种类。
Input

首先输入一个整数 T (1 <= T <= 10),代表有 T 组数据。
每组数据的第一行输入一个整数 n (1 <= n <= 100000) 和一个整数 q (1 <= q <= 100000),分别代表有 n 个小镇,表皮卡丘有 q 次操作。
接下来输入 q 行,对于每次操作,先输入操作类型:
1: 紧接着输入 2 个整数 a (1 <= a <= n), b (1 <= b <= 60),表示第 a 个小镇引入了第 b 种进化石。
2: 紧接着输入 2 个整数 a (1 <= a <= n), b (1 <= b <= 60),表示第 a 个小镇失去了全部第 b 种进化石。
3: 紧接着输入 2 个整数 l, r (1 <= l <= r <= n),表示他想询问从第 l 个到第 r 个小镇上可收集的进化石有哪几种。
Output

对于每组输入,首先输出一行 “Case T:”,表示当前是第几组数据。
每组数据中,对于每次操作 3,按编号升序输出所有可收集的进化石。如果没有进化石可收集,则输出一个 MeiK 的百分号 “%”。
Example Input

1
10 10
3 1 10
1 1 50
3 1 5
1 2 20
3 1 1
3 1 2
2 1 50
2 2 20
3 1 2
3 1 10
Example Output

Case 1:
%
50
50
20 50
%
%

其实不用状压也能过 我用的状压

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=100000;struct node{    ll num,fg;}tree[maxn<<4];void pushup(int id)  {      tree[id].num=tree[id<<1].num|tree[id<<1|1].num;  }  // void pushdown(int id)  // {  //     if(tree[id].fg)  //     {  //         tree[id<<1].num=tree[id<<1|1].num=(1ll<<tree[id].fg);  //         tree[id<<1].fg=tree[id<<1|1].fg=tree[id].fg;  //         tree[id].fg=0;  //     }  // }  // void build(int x,int l,int r)// {//     tree[x].fg=0;//     if(l==r)//     {//         tree[x].num=(1LL<<val[l]);//         return ;//     }//     int mid=(r+l)>>1;//     build(x<<1,l,mid);//     build(x<<1|1,mid+1,r);//     pushup(x);// }void update(int rt,int l,int r,int b,ll co,int flag){    if(l==r)    {        if(b==l)        {        if(flag)        tree[rt].num|=(1LL<<co);        else         tree[rt].num&=~(1LL<<co);        }        return;    }    // pushdown(rt);    int mid=(l+r)>>1;    if(b<=mid) update(rt<<1,l,mid,b,co,flag);    if(b>mid) update(rt<<1|1,mid+1,r,b,co,flag);    pushup(rt);}ll ans=0;void query(int rt,int l,int r,int L,int R){    if(L<=l&&r<=R)    {        ans|=tree[rt].num;        return ;    }    // pushdown(rt);    int mid=(l+r)>>1;    if(L<=mid) query(rt<<1,l,mid,L,R);    if(R>mid) query(rt<<1|1,mid+1,r,L,R);}int main(){    int t;    scanf("%d",&t);    for(int cc=1;cc<=t;cc++)    {        memset(tree,0,sizeof(tree));        printf("Case %d:\n",cc );        int n,m;        scanf("%d%d",&n,&m);        for(int i=1;i<=m;i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            if(a==1)            {                update(1,1,n,b,c,1);            }            if(a==2)            {                update(1,1,n,b,c,0);            }            if(a==3)            {                ans=0;                query(1,1,n,b,c);                if(ans==0)                {                    printf("%\n");                    continue;                }                int t=0;                for(int i=1;i<=63;i++)                {                    if(ans&(1LL<<i))                    {                        if(t)                        printf(" ");                        t++;                        printf("%d",i);                    }                }                printf("\n");            }        }    }}/***************************************************User name: 青大机器人Result: AcceptedTake time: 600msTake Memory: 2716KBSubmit time: 2017-06-04 20:57:38****************************************************/
原创粉丝点击