被线段树虐死了。。。
大体题意:
有一块板子,上面的颜色都为1.然后给你以下操作:
C A B C 把A-B染成C
P A B 询问A-B有几种颜色。
做法:
区域更新线段树。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 100010
struct list
{
int a,b;
int ct;
int color;
}node[maxn*4];
int n,t,o;
int ans;
int cnum[31];
void creat(int l,int r,int num)
{
node[num].a=l;
node[num].b=r;
node[num].color=(1<<1);
node[num].ct=0;
int mid;
mid=(l+r)/2;
if(r-l>=1)
{
creat(l,mid,num*2);
creat(mid+1,r,num*2+1);
}
}
void insert(int l,int r,int c,int num)
{
int a=node[num].a;
int b=node[num].b;
if(l==a&&r==b)
{
node[num].color=cnum[c];
node[num].ct=c;
return ;
}
int mid=(a+b)/2;
if(node[num].ct!=0)
{
node[num*2 ].ct=node[num].ct;
node[num*2 ].color=node[num].color;
node[num*2+1].ct=node[num].ct;
node[num*2+1].color=node[num].color;
node[num].ct=0;
}
if(mid>=r)
{
insert(l,r,c,num*2);
}
else if(mid<l)
{
insert(l,r,c,num*2+1);
}
else
{
insert(l,mid,c,num*2);
insert(mid+1,r,c,num*2+1);
}
node[num].color=node[num*2].color|node[num*2+1].color;
}
void search(int l,int r,int num)
{
int a,b,mid;
a=node[num].a;
b=node[num].b;
mid=(a+b)/2;
if(l<=node[num].a&&r>=node[num].b)
{
ans=ans|node[num].color;
return ;
}
else if((l>=node[num].a&&r<=node[num].b)&&node[num].ct!=0)
{
ans=ans|node[num].color;
return ;
}
if(mid>=r)
{
search(l,r,num*2);
}
else if(mid<l)
{
search(l,r,num*2+1);
}
else
{
search(l,mid,num*2);
search(mid+1,r,num*2+1);
}
}
int dos(int x)
{
int ns=0,i;
for(i=1;i<=30;i++)
{
if((x&(1<<i))!=0)ns++;
}
return ns;
}
int main()
{
int i;
for(i=1;i<=30;i++)
{
cnum[i]=(1<<i);
}
while(scanf("%d%d%d",&n,&t,&o)!=EOF)
{
creat(1,n,1);
getchar();
int a,b,c;
char ord;
while(o--)
{
scanf("%c",&ord);
if(ord=='C')
{
scanf("%d%d%d%*c",&a,&b,&c);
if(a>b)swap(a,b);
insert(a,b,c,1);
}
else if(ord=='P')
{
scanf("%d%d%*c",&a,&b);
if(a>b)swap(a,b);
ans=0;
search(a,b,1);
printf("%d\n",dos(ans));
}
}
}
return 0;
}