版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/83619130
【题目链接】
【思路要点】
- 使用一个简单的扫描线可以求出 在每个位置处的特征值。
- 时间复杂度 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e7 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } bool p[MAXN]; int seed, n, k, s; int getrand() { seed = ((seed * 12321) ^ 9999) % 32768; return seed; } void generateData() { scanf("%d%d%d", &k, &seed, &s); int t = 0; n = k * 2 + 1; for (int i = 1; i <= n; i++) { p[i] = getrand() >> 7 & 1; t += p[i]; } int i = 1; while(t > k) { while (p[i] == 0) i++; p[i] = 0; t--; } while(t < k) { while (p[i] == 1) i++; p[i] = 1; t++; } } int val[MAXN]; int solve(int x, bool type) { memset(val, 0, sizeof(val)); int cipher = k + 2, now = cipher, pos = cipher; for (int i = 1; i <= n; i++) if (p[i] ^ type) val[++pos]++; else pos--; int sum = 0; for (int i = now + 1; i <= n + 2; i++) sum += val[i]; for (int i = 1; i <= n; i++) { if (p[i] ^ type) sum -= val[++now], val[now]--; else sum += val[now--]; if (!p[i] && sum == x) return i; if (p[i] ^ type) { val[++pos]++; if (pos > now) sum++; } else pos--; } assert(false); return -1; } int main() { generateData(); printf("%d\n%d\n%d\n", solve(0, false), solve(s, false), solve(s, true)); return 0; }