【CDQ分治】 CF641E

题面

  • 题意 :

给定一个 带 时间戳可重集 (一开始为 空集), 每次进行以下几种操作。

  1. 在时刻 \(t\) 加入一个数 \(x\)

  2. 在时刻 \(t\) 删除一个数 \(x\)

  3. 在时刻 \(t\) 查询一个数 \(x\) 的出现次数

  • 思路 :

在线很棘手,考虑离线下来做。用一个状态四元组 \((tim, b,c, d)\) 去表示一个操作。

分别表示为 第 \(tim\) 个操作,第 \(op\) 种操作, 第 \(b\) 号时间,元素为 \(c\), 对于元素的出现次数影响为 \(d\) (若为查询则为 \(0\) ).

然后对于一个 第 \(tim\) 个操作为询问 的答案就是 :

\[\sum_{i < tim} \sum_{a[i].b \leq b,a[i].c = c}a[i].d \]

显然,这变成了一个三维偏序问题,做 \(CDQ\) 分治即可。
可以考虑容斥, 也可以开个桶去解决,后者加个离散化和前者一样。

  • 代码 :

桶使用 \(map\) 来实现,总时间复杂度为 \(O(n\log^2n)\)

// Coding by Custlo

// Tag : CDQ Method 

// Time : 2022 - 3 - 26

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <map>

using namespace std;

const int N = 2e5 + 5;

inline int read () {
    int ans = 0; char c = getchar(), last = ' ';
    while(c < '0' || c > '9') last = c,c = getchar();
    while(c >= '0' && c <= '9') ans = (ans << 1) + (ans << 3) + c - '0',c = getchar();
    return last == '-' ? - ans : ans;
}

map <int, int> exists; 

struct NODE {
	int a, b, c, op;
} a[N];
// 状态
inline bool cmp (NODE a, NODE b) { return a.a < b.a; }
inline bool cmp2 (NODE a, NODE b) { return a.b < b.b; }

int n, op[N], res[N];
inline void CdqMethod (int l, int r) {
	if (l == r) return ;
	int mid = (l + r) >> 1;
	CdqMethod(l, mid), CdqMethod(mid + 1, r);
	sort(a + l, a + r + 1, cmp2);
	for (int i = l; i <= r; i ++) {
		if (a[i].a <= mid ) {
            if (a[i].op != 3) exists[a[i].c] += (a[i].op == 1 ? 1 : -1); // 计算贡献
        }
        else if (a[i].op == 3) res[a[i].a] += exists[a[i].c]; // 求答案
	}
	for (int i = l; i <= r; i ++)
		if (a[i].a <= mid && a[i].op != 3) exists[a[i].c] -= (a[i].op == 1 ? 1 : -1); // 撤销贡献
	sort(a + l, a + r + 1, cmp);
} // cdq 分治
int main () {
	n = read();
	for (int i = 1; i <= n; i ++) {
		op[i] = a[i].op = read(), a[i].a = i, a[i].b = read(), a[i].c = read(); 
	}
	CdqMethod(1, n);
	for (int i = 1; i <= n; i ++) if (op[i] == 3) printf("%d\n", res[i]); // 输出答案
	return 0;
}
posted @ 2022-03-31 14:02  Cust10  阅读(53)  评论(0)    收藏  举报