BZOJ4377 Kurs szybkiego czytania Luogu 3589[POI2015]KUR

Solution

我又双叒叕去看题解啦$QAQ$, 真的想不到鸭

输入 $a$ 和 $n$ 互质, 所以满足 $a imes i mod n$ $(0<=i<n)$ 肯定是不重复的

根据这一个性质 , 设 满足条件的子串的开头位置为 $s$

先不考虑$01$, 仅考虑开头位置上的值 $a*s+b$, 设它为$x$, 则它接下来第 $i$ 位的值为 $x+(i-1)*a$

若那个位置上的字符为 $0$, 则 $0<=x+(i-1)*a<p$, 反之 $p<=x+(i-1)*a<n$

就可以列出$m$个不等式, 根据这$m$个不等式, 可以解出满足条件的$x$的范围和个数, 而 $x$ 与 开头位置$s$ 一 一对应, $x$的个数即为答案

但是实现解不等式的交集会比较麻烦, 所以先解出不满足条件的 $x$, 取并集

最后$m-1$个位置需要特别加入并集

Code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define N 1000005
 5 #define R register
 6 #define ll long long
 7 using namespace std;
 8 
 9 int n, a, b, p, m, tot, cnt;
10 char s[N];
11 
12 struct qj {
13     int s, t;
14 
15     bool operator < (const qj &b) const {
16         return s < b.s;
17     }
18 
19 }bt[N << 2];
20 
21 inline int cmax(int A, int B) {
22     return A > B ? A : B;
23 }
24 
25 int main()
26 {
27     scanf("%d%d%d%d%d", &n, &a, &b, &p, &m);
28     char ch = getchar();
29     while (ch != '0' && ch != '1') ch = getchar();
30     while (ch == '0' || ch == '1') s[++cnt] = ch, ch = getchar();
31     for (R int i = 1, j = 0; i <= m; ++i, j = (j + a) % n) {
32         ll x, y;
33         if (s[i] == '0') {
34             x = (p - j + n) % n;
35             y = (-1 - j + n) % n;
36         }
37         else {
38             x = (0 - j + n) % n;
39             y = (p - 1 - j + n) % n;
40         }
41         if (x <= y) {
42             bt[++tot].s = x;
43             bt[tot].t = y;
44         }
45         else {
46             bt[++tot].s = 0; bt[tot].t = y;
47             bt[++tot].s = x; bt[tot].t = n - 1;
48         }
49     }
50     for (R int i = n - m + 1, j = 1ll * i * a % n; i < n; ++i, j = (j + a) % n)
51         bt[++tot].s = (j + b) % n,
52         bt[tot].t = bt[tot].s;
53     sort(bt + 1, bt + 1 + tot);
54     int ans = 0, maxn = -1;
55     for (R int i = 1; i <= tot; ++i) {
56         if (bt[i].s > maxn) ans += bt[i].s - maxn - 1;
57         maxn = cmax(maxn, (int)bt[i].t);
58     }
59     if (maxn < n) ans += n - maxn - 1;
60     printf("%d
", ans);
61 }
View Code
原文地址:https://www.cnblogs.com/cychester/p/9856157.html