皮卡丘的梦想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: Accepted
Take time: 600ms
Take Memory: 2716KB
Submit time: 2017-06-04 20:57:38
****************************************************/