hdu 5372 Segment Game 【 树状数组 】

给出一些操作,

0是将第i次增加的线段放在b位置,第i次放的线段的长度为i

1是将第b次增加操作放的线段删除

每次增加操作完之后,询问这条线段上面的完整的线段的条数

每次询问统计比这条线段左端点大的线段的条数 L,比这条线段右端点大的线段的条数 R,两个相减就是完整的线段的条数

另外因为给的b很大,所以需要离散化一下,而且b可能会相同,所以相同大小的应该占据一个编号

然后就像求逆序对那样的算

  1 #include<iostream>  
  2 #include<cstdio>  
  3 #include<cstring> 
  4 #include <cmath> 
  5 #include<stack>
  6 #include<vector>
  7 #include<map> 
  8 #include<set>
  9 #include<queue> 
 10 #include<algorithm>  
 11 using namespace std;
 12 
 13 typedef long long LL;
 14 const int INF = (1<<30)-1;
 15 const int mod=1000000007;
 16 const int maxn=500005;
 17 
 18 int n;
 19 int a[maxn],c[maxn],b[maxn];
 20 
 21 int lowbit(int x){ return x &(-x);}
 22 
 23 int sum1(int x){
 24     int ret =0;
 25     while(x>0){
 26         ret+=c[x];x-=lowbit(x);
 27     }
 28     return ret;
 29 }
 30 
 31 void add1(int x,int d){
 32     while(x<=maxn){
 33         c[x]+=d;x+=lowbit(x);
 34     }
 35 }
 36 
 37 int sum2(int x){
 38     int ret =0;
 39     while(x>0){
 40         ret+=b[x];x-=lowbit(x);
 41     }
 42     return ret;
 43 }
 44 
 45 void add2(int x,int d){
 46     while(x<=maxn){
 47         b[x]+=d;x+=lowbit(x);
 48     }
 49 }
 50 
 51 struct node{
 52     int x,y;
 53     int l,r;
 54     int lb,ub;
 55     int id;
 56     int idx;
 57 };
 58 
 59 int cmp1(node n1,node n2){
 60     return n1.l < n2.l;
 61 }
 62 
 63 int cmp2(node n1,node n2){
 64     return n1.r < n2.r;
 65 }
 66 
 67 node p[maxn],cmd[maxn],add[maxn];
 68 
 69 int main(){
 70     int q;
 71     int kase = 0;
 72     while(scanf("%d",&q) != EOF){
 73         memset(a,0,sizeof(a));
 74         memset(b,0,sizeof(b));
 75         memset(c,0,sizeof(c));
 76         
 77         int cnt = 1;
 78         for(int i = 1;i <= q;i++){
 79             scanf("%d %d",&cmd[i].x,&cmd[i].y);
 80             if(cmd[i].x == 0){
 81                 cmd[i].id = cnt;
 82                 add[cnt].l = cmd[i].y; p[cnt].l = cmd[i].y;
 83                 add[cnt].r = add[cnt].l + cnt;p[cnt].r = add[cnt].l + cnt;
 84                 add[cnt].idx = cnt;p[cnt].idx = cnt;
 85                 cnt++;
 86             }
 87         }
 88         printf("Case #%d:
",++kase);
 89         
 90         sort(p+1,p+cnt,cmp1);
 91         for(int i=1,j=0;i< cnt;i++){
 92              if(i==1||p[i].l != p[i-1].l) j++;
 93              add[p[i].idx].lb=j;
 94          }
 95         
 96         sort(p+1,p+cnt,cmp2);
 97         for(int i=1,j=0;i< cnt;i++){
 98              if(i==1||p[i].r != p[i-1].r) j++;
 99              add[p[i].idx].ub=j;
100          }
101         
102         
103         for(int i = 1;i <= q;i++){
104             if(cmd[i].x == 0){
105                 int k = cmd[i].id;
106                 int c1 = add[k].lb;
107                 int c2 = add[k].ub;
108                 int l = (k-1) - sum1(c1 -1);
109                 int r = (k-1)- sum2(c2 );
110                 int ans = abs(l-r);
111                 printf("%d
",ans);
112                 add1(c1,1);add2(c2,1);
113             }
114             if(cmd[i].x == 1){
115                 int k = cmd[i].y;
116                 int c1 = add[k].lb;
117                 int c2 = add[k].ub;
118                 int d1 = sum1(c1) - sum1(c1-1);
119                 if(d1 != 0) add1(c1,-1);
120                 
121                 int d2 = sum2(c2) - sum2(c2-1);
122                 if(d2 != 0) add2(c2,-1);
123             }
124         }
125     }
126     return 0;
127 }
View Code
原文地址:https://www.cnblogs.com/wuyuewoniu/p/4723329.html