poj 2777 线段树
平生第一道线段树,A的太艰难了,一开始就RE,以为是数组开小了,增加了之后仍然RE,看了discuss后才知道文中有一就话没看到,“here A, B, C are integers, and A may be larger than B”,原来left可以大于right,改了之后结果TLE,我可纠结的不得了。后来看到一些大牛的博客中写道要用延迟操作,结果终于弄懂了什么是延迟操作。修改之后再提交结果WA(悲哉),后来自己做了一些测试数据,却发现自己仅在涂色的时候进行了延迟操作,其实在查找的时候仍然需要,修改之后AC了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAX_LEN 200010 struct node { int left; int right; int color; int sign; }; node tree[MAX_LEN*2]; int sum; int makeTree(int left,int right,int k) { int mid; tree[k].color=1; tree[k].left=left; tree[k].right=right; tree[k].sign=0; if(left==right) return 0; mid=(left+right)>>1; makeTree(left,mid,k<<1); makeTree(mid+1,right,(k<<1)+1); return 0; } inline int push(int k) { tree[k].sign=0; if(tree[k].left<tree[k].right) { tree[k<<1].color=tree[k].color; tree[(k<<1)+1].color=tree[k].color; tree[k<<1].sign=tree[(k<<1)+1].sign=1; } return 0; } int tintage(int left,int right,int color,int k) { int mid; if(tree[k].left==left && tree[k].right==right) { tree[k].color=1<<(color-1); tree[k].sign=1; return 0; } if(tree[k].sign) push(k); mid=(tree[k].left+tree[k].right)>>1; if(right<=mid) tintage(left,right,color,k<<1); else if(left>mid) tintage(left,right,color,(k<<1)+1); else { tintage(left,mid,color,k<<1); tintage(mid+1,right,color,(k<<1)+1); } tree[k].color=tree[k<<1].color|tree[(k<<1)+1].color; return 0; } int calculate(int color) { int i,j=1,k=0; for(i=0;i<30;j=(1<<++i)) if(color&j) k++; return k; } int query(int left,int right,int k) { int mid; if(tree[k].left==left && tree[k].right==right) { sum=sum|tree[k].color; return 0; } if(tree[k].sign) push(k); mid=(tree[k].left+tree[k].right)>>1; if(right<=mid) query(left,right,k<<1); else if(left>mid) query(left,right,(k<<1)+1); else { query(left,mid,k<<1); query(mid+1,right,(k<<1)+1); } return 0; } int main() { int i,m,n,len,color,left,right,temp; char c[10]; while(scanf("%d%d%d",&len,&m,&n)!=EOF) { makeTree(1,len,1); for(i=0;i<n;i++) { scanf("%s",c); if(c[0]=='C') { scanf("%d%d%d",&left,&right,&color); if(left>right) {temp=left,left=right,right=temp;} tintage(left,right,color,1); } if(c[0]=='P') { sum=0; scanf("%d%d",&left,&right); if(left>right) {temp=left,left=right,right=temp;} query(left,right,1); printf("%d\n",calculate(sum)); } } } return 0; }