Description
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.Input
First line of input contains L (1 <= L <= 100000), T (1 <= T <= 30) and O (1 <= O <= 100000). Here O denotes the number of operations. Following O lines, each contains "C A B C" or "P A B" (here A, B, C are integers, and A may be larger than B) as an operation defined previously.Output
Ouput results of the output operation in order, each line contains a number.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; }