传送门: http://acm.pku.edu.cn/JudgeOnline/problem?id=2777 线段树就不说了,这是我第一次写线段树,今天连过了两题,开心啊~直接贴代码吧。 #include<iostream> #include<memory> using namespace std; #define L 100005 #define T 31 struct C{int lt,rt,cl;}; C l[L*3]; bool t[T]; int sum; void create(int pos,int left,int right,int color) { if(left>right) swap(left,right); l[pos].lt=left; l[pos].rt=right; l[pos].cl=color; if(left==right) return; int mid=(left+right)/2; create(pos*2,left,mid,color); create(pos*2+1,mid+1,right,color); } void insert(int pos,int left,int right,int color) { if(left>right) return; if(l[pos].lt==left&&l[pos].rt==right) {l[pos].cl=color;return;} if(l[pos].cl>0){ l[pos*2].cl=l[pos].cl; l[pos*2+1].cl=l[pos].cl; l[pos].cl=0;} int mid=(l[pos].lt+l[pos].rt)/2; insert(pos*2,left,min(mid,right),color); insert(pos*2+1,max(mid+1,left),right,color); if(l[pos].cl==0&&l[pos*2].cl==l[pos*2+1].cl&&l[pos].lt!=l[pos].rt) l[pos].cl=l[pos*2].cl; return; } void search(int pos,int left,int right) { if(left>right) return; if(left>=l[pos].lt&&right<=l[pos].rt&&l[pos].cl>0) { if(!t[l[pos].cl]) {t[l[pos].cl]=true;sum++;} return; } else{ int mid=(l[pos].lt+l[pos].rt)/2; search(pos*2,left,min(mid,right)); search(pos*2+1,max(mid+1,left),right); return; } } int main(){ int ll,tt,oo,lft,rgt,clr; char cp; cin>>ll>>tt>>oo; create(1,1,ll,1); while(oo--) { cin>>cp; //scanf("%c",cp); if(cp=='C') { scanf("%d%d%d",&lft,&rgt,&clr); if(lft>rgt) swap(lft,rgt); insert(1,lft,rgt,clr); } else if(cp=='P') { scanf("%d%d",&lft,&rgt); if(lft>rgt) swap(lft,rgt); sum=0; memset(t,false,sizeof(t)); search(1,lft,rgt); printf("%d/n",sum); } } return 0; }