shjwudp

导航

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5372

题意:进行n次操作,操作分两种,0和1,每一个0操作按出现顺序有一个编号(从1开始

0操作 0 x:询问[x, x+i](i为该操作的编号)区间内有多少个完整的线段,并加入线段[x, x+i](线段直接重叠不影响)

1操作 1 x:删除0操作中插入的编号为x的线段,(不影响其他线段,不会重复删除同一线段,删除的线段一定是已经插入的)

解:题目有一个重要的条件:后面插入的线段一定比前面的长。那么考虑现在要插入线段[x, y],(-oo,x)有a个现存线段的左端点,(y,+oo)有b个现存线段的右端点,现存线段数为num个,则ans=num-a-b;用离散化+树状数组搞的话可以求出(-oo,y]内的右端点数c,有c=num-b;联立前式解得ans=c-a;

 1 /*
 2  * Problem: hdu5372 Segment Game 
 3  * Author:  SHJWUDP
 4  * Created Time:  2015/8/11 星期二 21:57:35
 5  * File Name: 1006.cpp
 6  * State: Accepted
 7  * Memo: 
 8  */
 9 #include <iostream>
10 #include <cstdio>
11 #include <vector>
12 #include <cstring>
13 #include <algorithm>
14 
15 using namespace std;
16 
17 struct Hash : vector<int> {
18     void prepare() {
19         sort(begin(), end());
20         erase(unique(begin(), end()), end());
21     }
22     int get(int x) {
23         return lower_bound(begin(), end(), x)-begin()+1;
24     }
25 };
26 struct Fenwick {
27     int n;
28     vector<int> c;
29     void init(int n) {
30         this->n=n;
31         c.assign(n+1, 0);
32     }
33     int lowbit(int x) {
34         return x & -x;
35     }
36     void add(int x, int v) {
37         while(x<=n) {
38             c[x]+=v; x+=lowbit(x);
39         }
40     }
41     int getsum(int x) {
42         int res=0;
43         while(x>0) {
44             res+=c[x]; x-=lowbit(x);
45         }
46         return res;
47     }
48 } fwl, fwr;
49 
50 int n;
51 vector<pair<int, int> > arr;
52 int main() {
53 #ifndef ONLINE_JUDGE
54     freopen("in", "r", stdin);
55     //freopen("out", "w", stdout);
56 #endif
57     int now=0;
58     while(~scanf("%d", &n)) {
59         arr.resize(n+1);
60         vector<pair<int, int> > A;
61         Hash hash;
62         int tmpLen=0;
63         for(int i=1; i<=n; i++) {
64             scanf("%d%d", &arr[i].first, &arr[i].second);
65             if(arr[i].first==0) {
66                 A.push_back(make_pair(arr[i].second,
67                             arr[i].second+(++tmpLen)));
68                 hash.push_back(A.back().first);
69                 hash.push_back(A.back().second);
70             }
71         }
72         hash.prepare();
73         fwl.init(hash.size()+2);
74         fwr.init(hash.size()+2);
75         int pos=0;
76         printf("Case #%d:\n", ++now);
77         for(int i=1; i<=n; i++) {
78             int a=arr[i].first;
79             int b=arr[i].second;
80             if(a==0) {
81                 int x=A[pos].first=hash.get(A[pos].first);
82                 int y=A[pos].second=hash.get(A[pos].second);
83                 pos++;
84                 printf("%d\n", fwr.getsum(y)-fwl.getsum(x-1));
85                 fwl.add(x, 1);
86                 fwr.add(y, 1);
87             } else {
88                 int x=A[b-1].first;
89                 int y=A[b-1].second;
90                 fwl.add(x, -1);
91                 fwr.add(y, -1);
92             }
93         }
94     }
95     return 0;
96 }
View Code

 

posted on 2015-08-11 23:01  shjwudp  阅读(164)  评论(0编辑  收藏  举报