成段更新,区间统计, 把query里的传递给子节点的步骤,切记!! 向大牛学习……http://www.notonlysuccess.com/?p=59 #include<iostream> using namespace std; int countbit(unsigned int n) { int count=0; while(n!=0) { n &= n-1; count++; } return count; } int two(int n) { return 1<<n; } struct seg_tree { int left; int right; int col; bool cover; int calmid() { return (left+right)>>1; } }; struct seg_tree tree[100000*3]; void build(int left,int right,int idx) { tree[idx].left = left; tree[idx].right = right; tree[idx].cover=1; tree[idx].col=two(1); if(left == right) return; int mid=tree[idx].calmid(); build(left,mid,idx<<1); build(mid+1,right,idx<<1|1); } int query(int left,int right,int idx) { if(left == tree[idx].left && right==tree[idx].right) { return tree[idx].col; } if(tree[idx].cover) { tree[idx<<1].col=tree[idx<<1|1].col=tree[idx].col; tree[idx<<1].cover=tree[idx<<1|1].cover=1; tree[idx].cover=0; } int mid=tree[idx].calmid(); if(right<=mid) return query(left,right,idx<<1); else if(left>mid) return query(left,right,idx<<1|1); else return query(left,mid,idx<<1) | query(mid+1,right,idx<<1|1); } void update(int left,int right,int val,int idx) { if(left <= tree[idx].left && right >= tree[idx].right ) { tree[idx].col=two(val); tree[idx].cover=1; return; } if(tree[idx].cover) { tree[idx<<1].col=tree[idx<<1|1].col=tree[idx].col; tree[idx<<1].cover=tree[idx<<1|1].cover=1; tree[idx].cover=0; } int mid=tree[idx].calmid(); if(left<=mid) update(left,right,val,idx<<1); if(right>mid) update(left,right,val,idx<<1|1); tree[idx].col=tree[idx<<1].col | tree[idx<<1|1].col; } int main() { freopen("in.txt","r",stdin); int n,m,p; cin>>n>>m>>p; build(1,n,1); while(p--) { char c; getchar(); scanf("%c",&c); if(c=='C') { int x,y,color; scanf("%d%d%d",&x,&y,&color); if(x>y) swap(x,y); update(x,y,color,1); } else if(c=='P') { int a,b; scanf("%d%d",&a,&b); if(a>b) swap(a,b); printf("%d/n",countbit(query(a,b,1))); } } return 0; }