ACdream 1157 Segments

Segments

Time Limit: 2000ms
Memory Limit: 10000KB
This problem will be judged on ACdream. Original ID: 1157
64-bit integer IO format: %lld      Java class name: (No Java Yet)
 

由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)
给出N,接下来N行,每行是3种类型之一

 

Input

多组数据,每组数据N

接下来N行,每行是三种操作之一(1 <= N  <= 10^5)

 

Output

对于每个Q操作,输出一行,答案
 

Sample Input

6
D 1 100
D 3 8
D 4 10
Q 3 8
C 1
Q 3 8

Sample Output

2
1

Hint

注意,删除第i条增加的线段,不是说第i行,而是说第i次增加。

比如

D 1 10

Q 1 10

D 2 3

D 3 4

Q 5 6

D 5 6

C 2是删除D 2 3

C 4是删除D 5 6

 

 

 

Source

 
解题:CDQ分治
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 300010;
 4 struct QU{
 5     int l,r,id,v;
 6     bool operator<(const QU &t) const{
 7         if(r != t.r) return r > t.r;
 8         if(l != t.l) return l < t.l;
 9         return id < t.id;
10     }
11     bool operator>(const QU &t) const{
12         return id < t.id;
13     }
14 }Q[maxn];
15 int bit[maxn],Li[maxn],ans[maxn],tot,n;
16 void update(int i,int val){
17     for(; i <= tot; i += i&(-i))
18         bit[i] += val;
19 }
20 int sum(int i,int ret = 0){
21     for(; i > 0; i -= i&(-i))
22         ret += bit[i];
23     return ret;
24 }
25 int d[maxn],cnt;
26 void cdq(int L,int R){
27     if(R <= L) return;
28     int mid = (L + R)>>1;
29     cdq(L,mid);
30     cdq(mid+1,R);
31     sort(Q+L,Q+R+1);
32     for(int i = L; i <= R; ++i){
33         if(Q[i].id <= mid && Q[i].v) update(Q[i].l,Q[i].v);
34         if(Q[i].id > mid && !Q[i].v) ans[Q[i].id] += sum(Q[i].l);
35     }
36     for(int i = L; i <= R; ++i)
37         if(Q[i].id <= mid && Q[i].v) update(Q[i].l,-Q[i].v);
38 }
39 int main(){
40     char op[10];
41     while(~scanf("%d",&n)){
42         memset(bit,0,sizeof bit);
43         memset(ans,0,sizeof ans);
44         for(int i = cnt = tot = 0; i < n; ++i){
45             scanf("%s",op);
46             Q[i].id = i;
47             if(op[0] == 'D'){
48                 scanf("%d%d",&Q[i].l,&Q[i].r);
49                 d[cnt++] = i;
50                 Q[i].v = 1;
51                 Li[tot++] = Q[i].l;
52                 Li[tot++] = Q[i].r;
53             }else if(op[0] == 'Q'){
54                 scanf("%d%d",&Q[i].l,&Q[i].r);
55                 Q[i].v = 0;
56                 Li[tot++] = Q[i].l;
57                 Li[tot++] = Q[i].r;
58             }else{
59                 scanf("%d",&Q[i].l);
60                 Q[i].r = Q[d[Q[i].l-1]].r;
61                 Q[i].l = Q[d[Q[i].l-1]].l;
62                 Q[i].v = -1;
63             }
64         }
65         sort(Li,Li + tot);
66         tot = unique(Li, Li + tot) - Li;
67         for(int i = 0; i < n; ++i){
68             Q[i].l = lower_bound(Li, Li + tot,Q[i].l) - Li + 1;
69             Q[i].r = lower_bound(Li, Li + tot,Q[i].r) - Li + 1;
70         }
71         cdq(0,n-1);
72         sort(Q,Q+n,greater<QU>());
73         for(int i = 0; i < n; ++i)
74             if(!Q[i].v) printf("%d\n",ans[Q[i].id]);
75     }
76     return 0;
77 }
View Code

 

posted @ 2015-08-14 15:30  狂徒归来  阅读(176)  评论(0编辑  收藏  举报