模板

来源:互联网 发布:孙悦在cba的数据 编辑:程序博客网 时间:2024/04/28 06:23
//二维线段树,矩阵里面的值为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;}


原创粉丝点击