CodeForces 669 E Little Artem and Time Machine CDQ分治

题目传送门

题意:现在有3种操作,

1 t x 在t秒往multiset里面插入一个x 

2 t x 在t秒从multiset里面删除一个x

3 t x 在t秒查询multiset里面有多少x

事情是按照输入顺序发生的,这个人有一个时光机,可以穿梭到那一秒去执行操作。

题解:CDQ分治。3维偏序,第一维是输入顺序,第二维t,然后直接map处理数据就好了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define lch(x) tr[x].son[0]
12 #define rch(x) tr[x].son[1]
13 #define max3(a,b,c) max(a,max(b,c))
14 #define min3(a,b,c) min(a,min(b,c))
15 typedef pair<int,int> pll;
16 const int inf = 0x3f3f3f3f;
17 const LL INF = 0x3f3f3f3f3f3f3f3f;
18 const LL mod =  (int)1e9+7;
19 const int N = 1e5 + 100;
20 struct Node{
21     int op, t, m, id;
22     bool operator < (const Node & x){
23         return t < x.t;
24     }
25 }A[N], tmp[N];
26 int ans[N];
27 map<int,int> mp;
28 void cdq(int l, int r){
29     if(l >= r) return ;
30     int mid = l + r >> 1;
31     cdq(l, mid);
32     cdq(mid+1, r);
33     int top = 0, tl = l, tr = mid + 1;
34     while(tl <= mid && tr <= r){
35         if(A[tl].t <= A[tr].t){
36             tmp[++top] = A[tl++];
37         }
38         else tmp[++top] = A[tr++];
39     }
40     while(tl <= mid){
41         tmp[++top] = A[tl++];
42     }
43     while(tr <= r){
44         tmp[++top] = A[tr++];
45     }
46     for(int i = 1; i <= top; i++){
47         int id = tmp[i].id, op = tmp[i].op;
48         int m = tmp[i].m;
49         if(id <= mid && op != 3){
50             if(op == 1) mp[m]++;
51             else mp[m]--;
52         }
53         else if(id > mid && op == 3){
54             ans[id] += mp[m];
55         }
56         A[l+i-1] = tmp[i];
57     }
58     for(int i = 1; i <= top; i++){
59         int id = tmp[i].id, op = tmp[i].op;
60         int m = tmp[i].m;
61         if(id <= mid && op != 3){
62             if(op == 1) mp[m]--;
63             else mp[m]++;
64         }
65     }
66 }
67 int main(){
68     int n;
69     scanf("%d", &n);
70     memset(ans, -1, sizeof(ans));
71     for(int i = 1; i <= n; i++){
72         scanf("%d%d%d", &A[i].op, &A[i].t, &A[i].m);
73         A[i].id = i;
74         if(A[i].op == 3) ans[i] = 0;
75     }
76     cdq(1,n);
77     for(int i = 1; i <= n; i++){
78         if(ans[i] == -1) continue;
79         printf("%d
", ans[i]);
80     }
81     return 0;
82 }
View Code
原文地址:https://www.cnblogs.com/MingSD/p/9747742.html