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\n", ans[i]); 80 } 81 return 0; 82 }