WolfDelaymasterHard
Topcoder #dp
\(\mathcal{O}(n^2)\) 的 \(dp\) 是容易的
考虑怎么优化,注意到对于 \(x\) 这个位置,它能贡献到的区间是 \(log\) 的
因为每遇到一个 o ,合法的左端点都会从当前位置扩大到 \(2\) 倍,所以最多有 \(log\) 次扩大,即 \(log\) 个可以贡献到的段
// Author: xiaruize
const int N = 4e6 + 10;
int n, wlen, w0, wmul, wadd, olen, o0, omul, oadd;
int pre[N];
int nxtw[N], nxto[N];
char s[N];
int dp[N], f[N];
void init()
{
cin >> n >> wlen >> w0 >> wmul >> wadd >> olen >> o0 >> omul >> oadd;
rep(i, 1, n) s[i] = '?';
int x = w0;
rep(i, 0, wlen - 1)
{
s[x + 1] = 'w';
x = (1ll * x * wmul + wadd) % n;
}
x = o0;
rep(i, 0, olen - 1)
{
s[x + 1] = 'o';
x = (1ll * x * omul + oadd) % n;
}
}
void solve()
{
init();
dp[0] = 1;
rep(i, 1, n * 2)
nxtw[i] = nxto[i] = n + 1;
rep(i, 1, n) pre[i] = (s[i] == 'w' ? i : pre[i - 1]);
per(i, n, 1)
{
nxtw[i] = (s[i] == 'w' ? i : nxtw[i + 1]);
nxto[i] = (s[i] == 'o' ? i : nxto[i + 1]);
}
rep(i, 0, n)
{
if (i)
(f[i] += f[i - 1]) %= MOD;
(dp[i] += f[i]) %= MOD;
if (i % 2 == 0)
{
int x = i + 1;
int nt = nxto[x];
while (x < nt)
{
if (pre[x * 2 - i] <= x)
{
int tmp = nxtw[x * 2 - i];
(f[x * 2 - i] += dp[i]) %= MOD;
(f[min((nt - 1) * 2 - i + 1, tmp)] += MOD - dp[i]) %= MOD;
x = tmp;
}
else
x = pre[x * 2 - i];
}
}
}
cout << dp[n] << endl;
}
#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--)
solve();
#ifndef ONLINE_JUDGE
cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
return 0;
}

浙公网安备 33010602011771号