//二维线段树,矩阵里面的值为0或者1,输入C,把从[x1,y1]到[x2,y2]区间内的值相反,//,输入Q,输出[x1,y1]的值#include <iostream>#include <cstdio>#include <string.h>using namespace std;const int N=1010;int n,m,ans;struct newtree{int left,right,value;int getnewmid(){ return (left+right)/2;}};struct tree{int left,right;newtree newtt[4*N];int getmid(){ return (left+right)/2;}}tt[4*N];void built_treey(int lp,int rp,int posx,int posy){//y方向建树tt[posx].newtt[posy].left=lp;tt[posx].newtt[posy].right=rp;tt[posx].newtt[posy].value=0;if(lp==rp)return;int mid=tt[posx].newtt[posy].getnewmid();built_treey(lp,mid,posx,posy*2);built_treey(mid+1,rp,posx,posy*2+1);}void built_treex(int lp,int rp,int pos){//x方向建树tt[pos].left=lp;tt[pos].right=rp;built_treey(1,n,pos,1);if(lp==rp)return;int mid=tt[pos].getmid();built_treex(lp,mid,pos*2);built_treex(mid+1,rp,pos*2+1);}void update_y(int y1,int y2,int posx,int posy){//更新y区间if(tt[posx].newtt[posy].left==y1&&tt[posx].newtt[posy].right==y2){ tt[posx].newtt[posy].value=!tt[posx].newtt[posy].value; return;}int mid=tt[posx].newtt[posy].getnewmid();if(y2<=mid)update_y(y1,y2,posx,posy*2);else if(y1>mid)update_y(y1,y2,posx,posy*2+1);else{ update_y(y1,mid,posx,posy*2); update_y(mid+1,y2,posx,posy*2+1);}}void update_x(int x1,int x2,int y1,int y2,int pos){//更新x区间值if(tt[pos].left==x1&&tt[pos].right==x2){ update_y(y1,y2,pos,1);//更新y区间值 return;}int mid=tt[pos].getmid();if(x2<=mid)update_x(x1,x2,y1,y2,pos*2);else if(x1>mid)update_x(x1,x2,y1,y2,pos*2+1);else{ update_x(x1,mid,y1,y2,pos*2); update_x(mid+1,x2,y1,y2,pos*2+1);}}void find_y(int y,int posx,int posy){//寻找yans^=tt[posx].newtt[posy].value;if(tt[posx].newtt[posy].left==tt[posx].newtt[posy].right)return;int mid=tt[posx].newtt[posy].getnewmid();if(y>mid)find_y(y,posx,posy*2+1);elsefind_y(y,posx,posy*2);}void find_x(int x,int y,int pos){//寻找xfind_y(y,pos,1);if(tt[pos].left==tt[pos].right)return;int mid=tt[pos].getmid();if(x>mid)find_x(x,y,pos*2+1);elsefind_x(x,y,pos*2);}int main(){//freopen("1.txt","r",stdin);int numcase;scanf("%d",&numcase);while(numcase--){ scanf("%d%d",&n,&m); built_treex(1,n,1); char ss[2]; int x1,x2,y1,y2,x,y; while(m--){ scanf("%s",ss);if(ss[0]=='C'){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); update_x(x1,x2,y1,y2,1);}else{ scanf("%d%d",&x,&y); ans=0; find_x(x,y,1); printf("%d\n",ans);} } puts("");}return 0;}
//题意,有n个房间,1是住房间,需要输出满足条件的最左面的房间号,2是//有人退房间#include <iostream>#include <cstdio>#include <string.h>using namespace std;const int N=50010;#define max(x,y) ((x)>(y)?(x):(y))struct tree{int left,right,flag;int lsum,rsum,sum;int getmid(){ return (left+right)/2;}void change(int pos);}tt[N*4];void tree::change(int pos){//lazy标签,向下传递 tt[pos*2].flag=tt[pos*2+1].flag=tt[pos].flag;int x,y;if(tt[pos].flag){ x=y=0;}else{ x=tt[pos*2].right-tt[pos*2].left+1; y=tt[pos*2+1].right-tt[pos*2+1].left+1;}tt[pos*2].lsum=tt[pos*2].rsum=tt[pos*2].sum=x;tt[pos*2+1].lsum=tt[pos*2+1].rsum=tt[pos*2+1].sum=y;tt[pos].flag=-1;}void built_tree(int lp,int rp,int pos){//建树tt[pos].left=lp;tt[pos].right=rp;tt[pos].flag=0;tt[pos].lsum=tt[pos].rsum=tt[pos].sum=rp-lp+1;if(lp==rp)return;int mid=tt[pos].getmid();built_tree(lp,mid,pos*2);built_tree(mid+1,rp,pos*2+1);}int find(int x,int pos){if(tt[pos].right==tt[pos].left){ return tt[pos].left;}if(tt[pos].flag!=-1){//lazy标签 tt[pos].change(pos);}if(tt[pos*2].sum>=x){//左面有满足的区间 return find(x,pos*2);}else if(tt[pos*2].rsum+tt[pos*2+1].lsum>=x){//中间有满足的区间 return tt[pos*2].right-tt[pos*2].rsum+1;}else if(tt[pos*2+1].sum>=x){//右面有满足的区间 return find(x,pos*2+1);}else{ return 0;}}void update(int lp,int rp,int modl,int pos){if(tt[pos].left==lp&&tt[pos].right==rp){if(modl==1){//modl=1,即入住房间,因此都为0 tt[pos].lsum=tt[pos].rsum=tt[pos].sum=0;}else{//modl=0,即退房间,因此为tt[pos].right-tt[pos].left+1tt[pos].lsum=tt[pos].rsum=tt[pos].sum=tt[pos].right-tt[pos].left+1;}tt[pos].flag=modl;return;}if(tt[pos].flag!=-1){//lazy标签,向下传递 tt[pos].change(pos);}int mid=tt[pos].getmid();if(rp<=mid)update(lp,rp,modl,pos*2);else if(lp>mid)update(lp,rp,modl,pos*2+1);else{ update(lp,mid,modl,pos*2); update(mid+1,rp,modl,pos*2+1);}//向上更新,更新父节点tt[pos].sum=max(max(tt[pos*2].sum,tt[pos*2+1].sum),tt[pos*2].rsum+tt[pos*2+1].lsum);tt[pos].lsum=tt[pos*2].lsum;tt[pos].rsum=tt[pos*2+1].rsum;if(tt[pos*2].lsum==tt[pos*2].right-tt[pos*2].left+1)tt[pos].lsum+=tt[pos*2+1].lsum;if(tt[pos*2+1].rsum==tt[pos*2+1].right-tt[pos*2+1].left+1)tt[pos].rsum+=tt[pos*2].rsum;}int main(){//freopen("1.txt","r",stdin);int n,m;while(~scanf("%d%d",&n,&m)){ built_tree(1,n,1); int mod,x,y,ans; while(m--){ scanf("%d",&mod);if(mod==1){ scanf("%d",&x); ans=0; ans=find(x,1); printf("%d\n",ans); if(ans){ update(ans,ans+x-1,1,1); }}else{ scanf("%d%d",&x,&y); update(x,x+y-1,0,1);} }}return 0;}
#include <iostream>#include <cstdio>using namespace std;const int N=100010;struct tree{int left,right,numcol;bool cover;}tt[N*4];int len,numcolour,numop,x,y;void build_tree(int lp,int rp,int pos){tt[pos].left=lp;tt[pos].right=rp;tt[pos].numcol=(1<<1);tt[pos].cover=true;//因为每个区间刚开始都涂有颜色if(lp==rp)return;int mid=(lp+rp)/2;build_tree(lp,mid,pos*2);build_tree(mid+1,rp,pos*2+1);}void add(int lp,int rp,int id,int pos){if(lp<=tt[pos].left&&rp>=tt[pos].right){tt[pos].cover=true;tt[pos].numcol=(1<<id);return;}if(tt[pos].cover){//lazy思想,向下传递tt[pos*2].cover=true;tt[pos*2+1].cover=true;tt[pos*2].numcol=tt[pos].numcol;tt[pos*2+1].numcol=tt[pos].numcol;tt[pos].cover=false;}int mid=(tt[pos].left+tt[pos].right)/2;if(lp<=mid)add(lp,rp,id,pos*2);if(rp>mid)add(lp,rp,id,pos*2+1);tt[pos].numcol=tt[pos*2].numcol|tt[pos*2+1].numcol;}int query(int lp,int rp,int pos){if(tt[pos].left==lp&&tt[pos].right==rp){return tt[pos].numcol;}if(tt[pos].cover){//lazy思想,向下传递tt[2*pos].cover=true;tt[2*pos+1].cover=true;tt[2*pos].numcol=tt[pos].numcol;tt[2*pos+1].numcol=tt[pos].numcol;tt[pos].cover=false;}int mid=(tt[pos].left+tt[pos].right)/2;if(lp>mid)return query(lp,rp,pos*2+1);else if(rp<=mid)return query(lp,rp,pos*2);elsereturn query(lp,mid,pos*2)|query(mid+1,rp,pos*2+1);}int fenjie(int x){int ans=0;while(x){ if(x%2) ans++; x/=2;}return ans;}int main(){//freopen("1.txt","r",stdin);while(~scanf("%d%d%d",&len,&numcolour,&numop)){ build_tree(1,len,1); char ss[2]; int id; while(numop--){ scanf("%s",ss);if(ss[0]=='C'){ scanf("%d%d%d",&x,&y,&id); if(x>y) swap(x,y); add(x,y,id,1);//[x,y]区间染色id}else{ scanf("%d%d",&x,&y); if(x>y) swap(x,y); int sum=query(x,y,1);//询问区间[x,y]的颜色总数 int total=fenjie(sum); printf("%d\n",total);} }}return 0;}
#include <iostream>#include <cstdio>#include <string.h>#include <algorithm>using namespace std;const int N=10010;struct tree{int left,right,num;}tt[16*N];int xx[N*4],yy[4*N],value[4*N],flag[4*N],ans;void built_tree(int lp,int rp,int pos){tt[pos].left=lp;tt[pos].right=rp;tt[pos].num=0;if(lp==rp)return;int mid=(tt[pos].left+tt[pos].right)/2;built_tree(lp,mid,pos*2);built_tree(mid+1,rp,pos*2+1);}int find(int x,int lp,int rp){while(lp<=rp){ int mid=(lp+rp)/2; if(value[mid]==x)return mid; else if(value[mid]>x) rp=mid-1; else lp=mid+1;}return -1;}void add(int lp,int rp,int id,int pos){if(lp<=tt[pos].left&&rp>=tt[pos].right){tt[pos].num=id;return;}if(tt[pos].num){ tt[2*pos].num=tt[2*pos+1].num=tt[pos].num; tt[pos].num=0;}int mid=(tt[pos].left+tt[pos].right)/2;if(lp<=mid)add(lp,rp,id,pos*2);if(rp>mid)add(lp,rp,id,pos*2+1);}void query(int lp,int rp,int pos){if(tt[pos].num){if(!flag[tt[pos].num]){ ans++; flag[tt[pos].num]=1;}return;}if(lp==rp)return;int mid=(tt[pos].left+tt[pos].right)/2;query(lp,mid,2*pos);query(mid+1,rp,2*pos+1);}int main(){//freopen("1.txt","r",stdin);int numcase;scanf("%d",&numcase);while(numcase--){ int n,pos=1; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d%d",&xx[i],&yy[i]);value[pos++]=xx[i];value[pos++]=yy[i]; } //built_tree(1,N,1); //离散化 sort(value+1,value+pos); int kk=2; for(int i=2;i<pos;++i){ if(value[i]!=value[i-1]){ value[kk++]=value[i]; } } for(int i=kk-1;i>1;--i){ if(value[i]!=value[i-1]+1){ value[kk++]=value[i-1]+1; } } sort(value+1,value+kk); //离散化完毕 built_tree(1,kk-1,1); for(int i=1;i<=n;++i){ int newx=find(xx[i],1,kk-1);//二分查找离散化后实际对应的值int newy=find(yy[i],1,kk-1);add(newx,newy,i,1); } memset(flag,0,sizeof(flag)); ans=0; query(1,kk-1,1); printf("%d\n",ans);}return 0;}