![]() | ||||||||||
| ||||||||||
A Corrupt Mayor's Performance ArtTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)Total Submission(s): 3098 Accepted Submission(s): 1126 Problem Description Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless painting at a high price to someone who wants to bribe him/her on an auction, this seemed a safe way for mayor X to make money.
Input There are several test cases.
Output For each query operation, print all kinds of color on the queried segments. For color 1, print 1, for color 2, print 2 ... etc. And this color sequence must be in ascending order.
Sample Input 5 10 P 1 2 3 P 2 3 4 Q 2 3 Q 1 3 P 3 5 4 P 1 2 7 Q 1 3 Q 3 4 P 5 5 8 Q 1 5 0 0
Sample Output 4 3 4 4 7 4 4 7 8
Source 2014 ACM/ICPC Asia Regional Guangzhou Online
Recommend hujie | We have carefully selected several similar problems for you: 6437 6436 6435 6434 6433
| ||||||||||
|
题目大意:
n段长度,m次操作。
每次操作都包涵一个op,若op为P;则随后紧跟着三个数a,b,c意味着a到b段全都渲染为c号颜色(0<c<=30);
若op为Q,则代表着一次询问,随后的两个数字a,b代表询问a到b段所有的颜色种类(升序输出);若某段长度不涉及P操作,
那么这段长度为2号颜色。
解题思路:
因为仅涉及30种颜色,所以仅用int型就可以表示所有的变化(二进制);具体思路见代码注释。
# include <iostream>
# include <cstdio>
# include <cstring>
# define ls k<<1,l,mid
# define rs k<<1|1,mid+1,r
using namespace std;
const int MAXN = 1000000+10;
int n,m,ans;
int sum[MAXN];
struct node
{
int l,r,add;
bool is_cor;//该节点是否需要传递
}tree[MAXN<<2];
void pushup(int k)//回溯,使该节点能记录其维护区间内的一切颜色
{
tree[k].add=(tree[k<<1].add|tree[k<<1|1].add);
return ;
}
void pushdown(int k)//传递,将该节点区域内的颜色全部改变该节点的颜色
{
if(tree[k].is_cor)
{
int mid=k<<1;
tree[mid].add=tree[k].add;
tree[mid].is_cor=1;
tree[mid|1].add=tree[k].add;
tree[mid|1].is_cor=1;
tree[k].is_cor=0;
}
return ;
}
void build(int k,int l,int r)//建树
{
tree[k].l=l;
tree[k].r=r;
tree[k].is_cor=0;
if(l==r)
{
tree[k].add=2;//第2位为1,意味着2号颜色
return ;
}
int mid=(l+r)>>1;
build(ls);
build(rs);
pushup(k);
return ;
}
void updata(int k,int l,int r,int add)
{
if(l<=tree[k].l&&tree[k].r<=r)//如果该节点全都需要改变颜色
{
tree[k].is_cor=1;//需要传递
tree[k].add=(1<<(add-1));//第add号颜色渲染
return ;
}
pushdown(k);//传递
int mid = (tree[k].l+tree[k].r)>>1;
if(r<=mid)
updata(k<<1,l,r,add);
else if(l>mid)
updata(k<<1|1,l,r,add);
else
{
updata(k<<1,l,mid,add);
updata(k<<1|1,mid+1,r,add);
}
pushup(k);//回溯
return ;
}
int query(int k,int l,int r)
{
if(l<=tree[k].l&&tree[k].r<=r)
{
return tree[k].add;
}
pushdown(k);
int res=0;
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid)
res|=query(k<<1,l,r);
else if(l>mid)
res|=query(k<<1|1,l,r);
else
{
res|=query(k<<1,l,mid);
res|=query(k<<1|1,mid+1,r);
}
return res;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n&&m)
{
build(1,1,n);
int a,b,c;
char ch[3];
while(m--)
{
scanf("%s",ch);
if(ch[0]=='P')
{
scanf("%d%d%d",&a,&b,&c);
updata(1,a,b,c);
}
else
{
scanf("%d%d",&a,&b);
int sz=0;
int res=query(1,a,b);
for(int i=0;i<30;i++)
if(res&(1<<i))
sum[sz++]=i+1;
for(int i=0;i<sz-1;i++)
cout<<sum[i]<<" ";
cout<<sum[sz-1]<<endl;
}
}
}
return 0;
}