Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 37779 | Accepted: 11355 |
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
这道题和just a hook差不多,在那道题的基础上加深了一些,每一次询问都要把数组a[]清空,然后往数组力添加代表不同颜色的数字,如果数组里已经有了该颜色就不用添加了。还学到了"<<"运算符,当它和"+"一起使用的时候,要加括号,因为其优先级小于"+",用位运算的速度确实比直接乘和除快啊。1<<i代表2的i次,i<<1代表i*2.
#include<stdio.h> #include<string.h> char s[10]; int a[100],t; struct node { int l,r,num; }b[4*200006]; void build(int l,int r,int i) { int mid; b[i].l=l;b[i].r=r;b[i].num=1; if(l==r)return; mid=(l+r)/2; build(l,mid,i<<1); build(mid+1,r,(i<<1)+1); } void update(int l,int r,int num,int i) { int mid; if(b[i].num==num)return; if(b[i].l==l && b[i].r==r){ b[i].num=num;return; } if(b[i].num!=-1){ b[i<<1].num=b[(i<<1)+1].num=b[i].num;b[i].num=-1; } mid=(b[i].l+b[i].r)/2; if(r<=mid)update(l,r,num,i<<1); else if(l>mid) update(l,r,num,(i<<1)+1); else if(r>mid && l<=mid) { update(l,mid,num,i<<1);update(mid+1,r,num,(i<<1)+1); } } void question(int l,int r,int i) { int mid,j,flag; if(b[i].num!=-1){ flag=1; for(j=1;j<=t;j++){ if(a[j]==b[i].num){ flag=0;break; } } if(flag==1){ a[++t]=b[i].num; } return; } mid=(b[i].l+b[i].r)/2; if(r<=mid) question(l,r,i<<1); else if(l>mid) question(l,r,(i<<1)+1); else { question(l,mid,i<<1); question(mid+1,r,(i<<1)+1); } } int main() { int n,m,i,j,c,d,e,T,temp,num,h; while(scanf("%d%d%d",&n,&m,&T)!=EOF) { build(1,n,1); for(i=1;i<=T;i++){ scanf("%s",s); if(s[0]=='C'){ scanf("%d%d%d",&c,&d,&e); if(c>d){ temp=c;c=d;d=temp; } update(c,d,e,1); } else if(s[0]=='P'){ scanf("%d%d",&c,&d); if(c>d){ temp=c;c=d;d=temp; } memset(a,0,sizeof(a)); t=0; question(c,d,1); printf("%d\n",t); } } } return 0; }