CF889E Mod Mod Mod

CF889E Mod Mod Mod

一道有趣的题,考虑\(x\)有意义的取值,设\(f_i\)表示\(x \bmod a_1 ... \bmod a_i\)的值,那么一定存在\(f_k = a_k - 1\),否则我们可以让\(x\)整体加一直到达到上界,这样显然更优,所以\(x\)有意义的取值只有\(O(n)\)个,这样我们可以\(DP\)去维护这些取值的答案。具体的,设\(g_{i,j}\)表示到第\(i\)轮,在\(\bmod a_i\)后的值为\(j\)高于当前数的和,这样答案就为\(g_{i,j} + ij\)

\[g_{i+1,j \bmod a_{i + 1}} = \max{g_{i,j} + i * (j - j \bmod a_{i + 1})} \]

\[g_{i+1,a_{i+1} - 1} = \max{g_{i,j} + i * ((j + 1) / a_{i+1} * a_{i + 1} - a_{i+1})} \]

\(map\)来转移\(DP\)

Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#define LL long long
#define IN inline
using namespace std;
const int N = 2e5 + 5;
int n; LL a[N];

IN LL read() {
	LL res = 0; char ch = getchar();
	for (; !isdigit(ch); ch = getchar());
	for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (LL)(ch ^ 48);
	return res;
}
map<LL, LL> f;
int main() {
	n = read();
	for (LL i = 1; i <= n; i++) a[i] = read();
	f[a[1] - 1] = 0;
	for (int i = 2; i <= n; i++) {
		for (auto j = f.lower_bound(a[i]); j != f.end(); f.erase(j++)) {
			LL v = j->first % a[i], g = j->first;
			f[v] = max(f[v], j->second + (LL)(i - 1) * (g - v));
			f[a[i] - 1] = max(f[a[i] - 1], j->second + (LL)(i - 1) * ((g + 1) / a[i] * a[i] - a[i]));
		}
	}
	LL ans = 0;
	for (auto i : f) ans = max(ans, i.second + (LL)n * i.first);
	printf("%lld\n", ans);
}

posted @ 2022-11-25 19:32  RiverSheep  阅读(43)  评论(0)    收藏  举报