Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 36646 | Accepted: 11053 |
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
题意就是求一段墙壁颜色种类,因为颜色种类最多30,可以用二进制表示颜色的总数。
#include
#include
#include
#include
#include
using namespace std;
#define ll __int64
#define N 100005
struct node
{
int l,r;
int s,v,f; //颜色种类二级制表示,区间颜色、是否需要向下更新
}f[N*3];
void creat(int t,int l,int r)
{
f[t].l=l;
f[t].r=r;
f[t].v=1;
f[t].f=0;
f[t].s=1; //起始颜色为1,可以用二进制表示
if(l==r)
{
return ;
}
int tmp=t<<1,mid=(l+r)>>1;
creat(tmp,l,mid);
creat(tmp|1,mid+1,r);
}
void update(int t,int l,int r,int v)
{
int tmp=t<<1,mid=(f[t].l+f[t].r)>>1;
if(f[t].l==l&&f[t].r==r)
{
f[t].v=v;
f[t].s=(1<mid)
update(tmp|1,l,r,v);
else
{
update(tmp,l,mid,v);
update(tmp|1,mid+1,r,v);
}
f[t].f=0; //向上求和
f[t].s=f[tmp].s|f[tmp|1].s;
}
int query(int t,int l,int r)
{
if(f[t].l==l&&f[t].r==r)
{
return f[t].s;
}
int tmp=t<<1,mid=(f[t].l+f[t].r)>>1;
if(f[t].f)
{
f[tmp].f=f[tmp|1].f=1;
f[tmp].v=f[tmp|1].v=f[t].v;
f[tmp].s=f[tmp|1].s=(1<mid)
return query(tmp|1,l,r);
else
{
return query(tmp,l,mid)|query(tmp|1,mid+1,r);
}
}
int main()
{
int n,t,q,l,r,c;
char ch;
while(~scanf("%d%d%d",&n,&t,&q))
{
creat(1,1,n);
while(q--)
{
getchar();
scanf("%c ",&ch);
if(ch=='C')
{
scanf("%d%d%d",&l,&r,&c);
if(l>r)
swap(l,r);
update(1,l,r,c-1);
}
else
{
scanf("%d%d",&l,&r);
if(l>r)
swap(l,r);
int tmp=query(1,l,r),ans=0;
while(tmp)
{
if(tmp&1)
ans++;
tmp>>=1;
}
printf("%d\n",ans);
}
}
}
return 0;
}