成段更新,在節點處lazy標記有很大協助,有了lazy標記每次更新時就不用更新到底了。
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 100005int n,m,t,sum;char str[2];bool color[33];struct TNode{ int l,r,color;} node[4*N];void build(int root,int l,int r){ node[root].color=1; node[root].l=l,node[root].r=r; if(l+1>=r) return ; int mid=(l+r)>>1,p=root<<1; build(p,l,mid); build(p+1,mid,r);}void insert(int root,int l,int r,int c){ int mid,p=root<<1; if(node[root].l==l&&node[root].r==r) { node[root].color=c; return ; } if(node[root].color==c) return ; if(node[root].color>0) { node[p].color=node[root].color; node[p+1].color=node[root].color; node[root].color=0; } mid=(node[root].l+node[root].r)>>1; if(r<=mid) insert(p,l,r,c); else if(l>=mid) insert(p+1,l,r,c); else { insert(p,l,mid,c); insert(p+1,mid,r,c); }}void query(int root,int l,int r){ int mid,p; if(node[root].color>0) { if(!color[node[root].color]) { color[node[root].color]=1; sum++; } return ; } mid=(node[root].l+node[root].r)>>1; p=root<<1; if(r<=mid) query(p,l,r); else if(l>=mid) query(p+1,l,r); else { query(p,l,mid); query(p+1,mid,r); }}int main(){ scanf("%d%d%d",&n,&m,&t); int l,r,c; build(1,0,n); while(t--) { scanf("%s%d%d",str,&l,&r); if(l>r) swap(l,r); if(str[0]=='C') { scanf("%d",&c); insert(1,l-1,r,c); } else { memset(color,0,sizeof(color)); sum=0; query(1,l-1,r); printf("%d\n",sum); } } return 0;}