BZOJ4377: [POI2015]Kurs szybkiego czytania
这题挺神仙的
注意一些比较显然的性质
1.gcd(a, n) = 1, 所以 a * i % n 的结果互不相同,
所以 (a * i % n + b) % n 的结果也互不相同
2. (a * i + b) % n 的结果是每个差了 + a 再 % n 的
对于每个位置,它的值为 0 / 1 都会分别对应一个方程
设某个匹配位置的起始点为 bgn,该点的值为 val
那么它后面的值就是 (val + a) % n
就是说当起点固定时,后面每个位置上的值就都确定了
其实后边的点也是可以推起点的,
例如当 b[i] = 0 时,设起点的值为 val
那么 b[i] = 0 的条件就是 0 ≤ (val + (i - 1) * a) % n < p
这样可以给 val 求出一个值域,那么对每一个位置求出的值域求交就是 val 合法的值
求交不太好求?
可以补集转化,求补集的并集
代码:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cctype> #include <cstdio> #include <locale> using namespace std; typedef long long ll; const int MAX_M = 1000005; struct INTERVAL { int l, r; explicit INTERVAL(int L = 0, int R = 0) {l = L; r = R;} bool operator < (const INTERVAL& b) const { return l < b.l; } }line[MAX_M * 3]; int n, a, b, p, m, tot_line; int seq[MAX_M]; inline int rd() { register int x = 0; register int c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) { x = x * 10 + (c ^ 48); c = getchar(); } return x; } inline void get_str(int *str) { register int c = getchar(), len = 0; while (!isdigit(c)) c = getchar(); while (isdigit(c) && len < m) { str[++len] = (c ^ 48); c = getchar(); } } inline void add(int l, int r) { if (l <= r) line[++tot_line] = INTERVAL(l, r); else { line[++tot_line] = INTERVAL(l, n - 1); line[++tot_line] = INTERVAL(0, r); } } int main() { n = rd(); a = rd(); b = rd(); p = rd(); m = rd(); get_str(seq); register int lef, rig; for (int i = 1; i <= m; ++i) { if (seq[i] == 0) { lef = int((p - ((i - 1ll) * a) % n + n) % n); rig = int((n - 1ll - ((i - 1ll) * a) % n) % n); } else { lef = int((0 - ((i - 1ll) * a % n) + n) % n); rig = int((p - 1ll - ((i - 1ll) * a % n) + n) % n); } add(lef, rig); } register int tmp = 0; for (int i = n - m + 1; i < n; ++i) { tmp = int((1ll * a * i % n + b) % n); add(tmp, tmp); } sort(line + 1, line + tot_line + 1); register ll ans = 0ll; register int max_rig = -1ll; for (int i = 1; i <= tot_line; ++i) { if (line[i].l > max_rig) ans += line[i].l - max_rig - 1ll; max_rig = max(max_rig, line[i].r); } printf("%lld\n", ans + (n - max_rig - 1ll)); return 0; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/