当前位置: 代码迷 >> 综合 >> luogu P3750 [六省联考 2017]分手是祝愿
  详细解决方案

luogu P3750 [六省联考 2017]分手是祝愿

热度:79   发布时间:2023-12-29 23:59:13.0

https://www.luogu.com.cn/problem/P3750

k=nk=nk=n给了808080分可还行
首先考虑k=nk=nk=n,不难想到一个贪心,从大到小枚举每个开关,如果为111就把按,这样一定是最优的,就做完了

考虑k<nk<nk<n,先跑一边上面的得到gsgsgs

把期望的式子写出来E(i)=inE(i?1)+n?inE(i+1)+1E(i)=\frac{i}{n}E(i-1)+\frac{n-i}{n}E(i+1)+1E(i)=ni?E(i?1)+nn?i?E(i+1)+1
最少还要iii步的时候,期望几步能搞完,显然E(k)=kE(k)=kE(k)=k
这显然是个带状矩阵,可以直接上带状矩阵高斯消元,不过我写的是手动消元
答案就是E(gs)E(gs)E(gs)

code:

#include<bits/stdc++.h>
#define ll long long
#define mod 100003
#define N 200050
using namespace std;
ll qpow(ll x, ll y) {
    ll ret = 1;for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;return ret;
}
struct A {
    ll a, b, c, d;
} v[N];
int n, k, a[N];
ll E[N];
vector<int> d[N];
int main() {
    scanf("%d%d", &n, &k);for(int i = 1; i <= n; i ++)for(int j = i; j <= n; j += i) d[j].push_back(i);for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);int gs = 0;for(int i = n; i >= 1; i --) if(a[i]) {
    for(int x : d[i]) a[x] ^= 1;gs ++;}ll ans = 0;if(gs <= k) ans = gs;else {
    //wdnmd 不会啊// E[k] = k;// for(int i = k; i <= gs; i ++) E[i + 1] = (E[i] - i * qpow(n, mod - 2) % mod * E[i - 1] % mod - 1 + mod) % mod * n % mod * qpow(n - i, mod - 2) % mod;// for(int i = k; i <= gs; i ++) printf("%lld ", E[i]); printf("\n");E[k] = k;for(int i = k + 1; i <= n; i ++) {
    v[i].a = i * qpow(n, mod - 2) % mod;v[i].b = mod - 1;v[i].c = (n - i) * qpow(n, mod - 2) % mod;v[i].d = mod - 1;}for(int i = n - 1; i >= k; i --) {
    ll bs = v[i].c * qpow(v[i + 1].b, mod - 2) % mod;v[i].b = (v[i].b - bs * v[i + 1].a % mod + mod) % mod;v[i].c = (v[i].c - bs * v[i + 1].b % mod + mod) % mod;v[i].d = (v[i].d - bs * v[i + 1].d % mod + mod) % mod;}   for(int i = k + 1; i <= n; i ++) {
    ll bs = qpow(v[i].b, mod - 2) % mod;E[i] = (v[i].d - v[i].a * E[i - 1] % mod + mod) % mod * bs % mod;}// for(int i = k; i <= n; i ++) printf("%lld ", E[i]); printf("\n");ans = E[gs];    }for(int i = 1; i <= n; i ++) ans = ans * i % mod;printf("%lld", ans);return 0;
}

看了眼题解,发现了一个nb的东西
可以考虑把期望的定义差分,E(i)E(i)E(i)表示从iii变成i?1i-1i?1期望要几步

显然E(i)=n?in(E(i+1)+E(i))+1E(i)=\frac{n-i}{n}(E(i+1)+E(i))+1E(i)=nn?i?(E(i+1)+E(i))+1
就是说可能变多了一步,然后又变回去,
移一下项变成E(i)=(n?i)E(i+1)i+niE(i)=\frac{(n-i)E(i+1)}{i}+\frac{n}{i}E(i)=i(n?i)E(i+1)?+in?
然后直接倒过来递推即可

然后在把E(k)E(k)E(k)E(gs)E(gs)E(gs)加起来即可

code:

懒得写