其他分享
首页 > 其他分享> > CF1718C Tonya and Burenka-179

CF1718C Tonya and Burenka-179

作者:互联网

显然只需要考虑 \(k\vert n\)。如果直接维护是 \(O(nd(n)\log n)\) 的,很寄。

可以证明如果 \(\frac{n}{k}\) 不是素数则不优。这个很好理解,比如对于 \(n=12,k=2,6\),所有 \(k=2\) 的方案一定可以被三个 \(k=6\) 的走法完全覆盖,而且这三个走法平均数还和这个 \(k=2\) 方案一样,那么只考虑 \(k=6\) 肯定不劣。

时间复杂度降为 \(O(n\omega(n)\log n)\)

#include <cstdio>
#include <algorithm>
#include <queue>
#define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++)

typedef long long ll;
char buf[100000], *p1, *p2;
inline int read() {
	char ch;
	int x = 0;
	while ((ch = gc) < 48);
	do x = x * 10 + ch - 48; while ((ch = gc) >= 48);
	return x;
}

struct heap {
	std::priority_queue<ll> Q1, Q2;
	void clear() {
		while (Q1.size()) Q1.pop();
		while (Q2.size()) Q2.pop();
	}
	inline void push(ll x) {Q1.push(x);}
	inline void pop(ll x) {Q2.push(x);}
	inline ll top() {
		while (Q2.size() && Q1.top() == Q2.top()) Q1.pop(), Q2.pop();
		return Q1.top();
	}
} Q[10];
int a[200005], b[10];
ll val[10][200005];

signed main() {
	int _ = read();
	while (_ --) {
		int n = read(), q = read(), cnt = 0, tmp = n;
		for (int i = 1; i <= n; ++ i) a[i] = read();
		tmp = n;
		for (int i = 2; i <= tmp; ++ i) if (tmp % i == 0) {
			while (tmp % i == 0) tmp /= i;
			b[++ cnt] = n / i, Q[cnt].clear();
		}
		long long ans = 0;
		for (int i = 1; i <= cnt; ++ i)
		for (int j = 1; j <= b[i]; ++ j) {
			val[i][j] = 0;
			for (int k = j; k <= n; k += b[i]) val[i][j] += a[k];
			Q[i].push(val[i][j] * b[i]), ans = std::max(ans, val[i][j] * b[i]);
		}
		printf("%lld\n", ans);
		while (q --) {
			int p, x;
			p = read(), x = read();
			ans = 0;
			for (int i = 1; i <= cnt; ++ i) {
				int j = (p - 1) % b[i] + 1;
				Q[i].pop(val[i][j] * b[i]), Q[i].push((val[i][j] += x - a[p]) * b[i]);
				ans = std::max(ans, Q[i].top());
			}
			a[p] = x;
			printf("%lld\n", ans);
		}
	}
	return 0;
}

标签:Q1,Burenka,Q2,int,ll,pop,Tonya,while,CF1718C
来源: https://www.cnblogs.com/stinger/p/16609997.html