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 }