• ACdream1157 Segments(CDQ分治 + 线段树)


    题目这么说的:

    进行如下3种类型操作:
    1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]
    2)C i (1-base) 删除第i条增加的线段,保证每条插入线段最多插入一次,且这次删除操作一定合法
    3) Q L R(1 <= L <= R <= 1000000000) 查询目前存在的线段中有多少条线段完全包含[L,R]这个线段,线段X被线段Y完全包含即LY <= LX <= RX <= RY)

    初学CDQ分治是看了Balkan OI 2007 Mokia那题的解法。两题类似,这题做法也不难想出:

    • 每次对操作的区间进行分治时,统计左半边更新操作对右半边查询操作的影响,影响的前提是更新操作的L小于等于查询操作的L且R要大于等于查询的R,这个通过一开始把L按从小到大排序,分治时便可从大到小遍历,同时用线段树维护R出现次数即可。

    其实我一开始看错题,以为询问的是有几条线段包含在给定区间里面,写完后发现才样例过不了。。不过改一下就好了,然后1A感觉还是不错的。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 int tree[222222<<2],N,x,y;
      7 void update(int i,int j,int k){
      8     if(i==j){
      9         tree[k]+=y;
     10         return;
     11     }
     12     int mid=i+j>>1;
     13     if(x<=mid) update(i,mid,k<<1);
     14     else update(mid+1,j,k<<1|1);
     15     tree[k]=tree[k<<1]+tree[k<<1|1];
     16 }
     17 int query(int i,int j,int k){
     18     if(x<=i && j<=y){
     19         return tree[k];
     20     }
     21     int mid=i+j>>1,res=0;
     22     if(x<=mid) res+=query(i,mid,k<<1);
     23     if(y>mid) res+=query(mid+1,j,k<<1|1);
     24     return res;
     25 }
     26 
     27 struct Query{
     28     int idx,type,anspos;
     29     int x,y;
     30     bool operator<(const Query &q)const{
     31         return x<q.x;
     32     }
     33 }que[111111],tmp[111111];
     34 
     35 int ans[111111];
     36 
     37 void cdq(int l,int r){
     38     if(l>=r) return;
     39     int mid=l+r>>1,i=l,j=mid+1;
     40     for(int k=l; k<=r; ++k){
     41         if(que[k].idx<=mid) tmp[i++]=que[k];
     42         else tmp[j++]=que[k];
     43     }
     44     for(int k=l; k<=r; ++k) que[k]=tmp[k];
     45 
     46     for(i=mid+1,j=l; i<=r; ++i){
     47         if(que[i].type!=3) continue;
     48         for( ; j<=mid && que[j].x<=que[i].x; ++j){
     49             if(que[j].type==3) continue;
     50             x=que[j].y; y=(que[j].type==1) ? 1 : -1;
     51             update(0,N-1,1);
     52         }
     53         x=que[i].y; y=N-1;
     54         ans[que[i].anspos]+=query(0,N-1,1);
     55     }
     56     for(i=l; i<j; ++i){
     57         if(que[i].type==3) continue;
     58         x=que[i].y; y=(que[i].type==1) ? -1 : 1;
     59         update(0,N-1,1);
     60     }
     61     cdq(l,mid); cdq(mid+1,r);
     62 }
     63 
     64 int segx[111111],segy[111111],sn;
     65 int point[222222],pn;
     66 int main(){
     67     char op;
     68     int n,a,b;
     69     while(~scanf("%d",&n)){
     70         int cnt=0;
     71         memset(ans,0,sizeof(ans));
     72         sn=0; pn=0;
     73         for(int i=0; i<n; ++i){
     74             scanf(" %c",&op);
     75             if(op=='D'){
     76                 scanf("%d%d",&a,&b);
     77                 segx[++sn]=a; segy[sn]=b;
     78                 point[pn++]=a; point[pn++]=b;
     79                 que[i].idx=i; que[i].type=1; que[i].x=a; que[i].y=b;
     80             }else if(op=='C'){
     81                 scanf("%d",&a);
     82                 que[i].idx=i; que[i].type=2; que[i].x=segx[a]; que[i].y=segy[a];
     83             }else{
     84                 scanf("%d%d",&a,&b);
     85                 point[pn++]=a; point[pn++]=b;
     86                 que[i].idx=i; que[i].type=3; que[i].x=a; que[i].y=b; que[i].anspos=++cnt;
     87             }
     88         }
     89 
     90         sort(point,point+pn);
     91         pn=unique(point,point+pn)-point;
     92         for(N=1; N<pn; N<<=1);
     93 
     94         for(int i=0; i<n; ++i){
     95             que[i].x=lower_bound(point,point+pn,que[i].x)-point;
     96             que[i].y=lower_bound(point,point+pn,que[i].y)-point;
     97         }
     98 
     99         sort(que,que+n);
    100         cdq(0,n-1);
    101 
    102         for(int i=1; i<=cnt; ++i){
    103             printf("%d
    ",ans[i]);
    104         }
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    tf.get_variable
    tf.Variable
    tf.placeholder
    conda命令详解
    linux查看程序运行时占用的内存
    ubuntu安装openssh-server
    sed命令
    二分查找
    vue简单使用
    斐波那契数列求解
  • 原文地址:https://www.cnblogs.com/WABoss/p/5701844.html
Copyright © 2020-2023  润新知