题面
Sol
首先从大向小,能关就关显然是最优
然后
设
f[i]
f
[
i
]
表示剩下最优要按i个开关的期望步数,倒推过来就是
f[i]=f[i−1]∗i∗inv[n]+f[i+1]∗(n−i)∗inv[n]+1
f
[
i
]
=
f
[
i
−
1
]
∗
i
∗
i
n
v
[
n
]
+
f
[
i
+
1
]
∗
(
n
−
i
)
∗
i
n
v
[
n
]
+
1
inv i n v 表示逆元
设 g[i]=f[i]−f[i−1] g [ i ] = f [ i ] − f [ i − 1 ]
那么上式变为
∑j=1ig[i]=∑j=1i−1g[i]∗i∗inv[n]+∑j=1i+1g[i]∗(n−i)∗inv[n]+1
∑
j
=
1
i
g
[
i
]
=
∑
j
=
1
i
−
1
g
[
i
]
∗
i
∗
i
n
v
[
n
]
+
∑
j
=
1
i
+
1
g
[
i
]
∗
(
n
−
i
)
∗
i
n
v
[
n
]
+
1
化简
g[i]=(g[i]+g[i+1])∗(n−i)∗inv[n]+1g[i]=((n−i)∗g[i+1]+n)∗inv[i]
g
[
i
]
=
(
g
[
i
]
+
g
[
i
+
1
]
)
∗
(
n
−
i
)
∗
i
n
v
[
n
]
+
1
g
[
i
]
=
(
(
n
−
i
)
∗
g
[
i
+
1
]
+
n
)
∗
i
n
v
[
i
]
边界 g[n+1]=0 g [ n + 1 ] = 0
最后就记个前缀和就好了
# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(1e5 + 5);
const int Zsy(100003);
IL ll Input(){
RG ll x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
int n, k, step, facn = 1, inv[_], f[_], ans;
bool sta[_], nxt[_];
IL void Up(RG int &x, RG int y){
x += y;
if(x >= Zsy) x -= Zsy;
}
int main(RG int argc, RG char* argv[]){
n = Input(); k = Input();
for(RG int i = 1; i <= n; ++i) facn = 1LL * facn * i % Zsy, sta[i] = Input();
for(RG int i = n; i; --i){
RG bool g = sta[i];
for(RG int j = i + i; j <= n; j += i) g ^= nxt[j];
if(g) nxt[i] = 1, ++step;
}
if(step <= k) return printf("%lld\n", 1LL * facn * step % Zsy), 0;
inv[1] = 1;
for(RG int i = 2; i <= n; ++i) inv[i] = (-1LL * (Zsy / i) * inv[Zsy % i] % Zsy + Zsy) % Zsy;
for(RG int i = 1; i <= k; ++i) f[i] = 1;
for(RG int i = n; i > k; --i) f[i] = 1LL * inv[i] * (1LL * (n - i) * f[i + 1] % Zsy + n) % Zsy;
for(RG int i = 1; i <= step; ++i) Up(ans, f[i]);
printf("%lld\n", 1LL * facn * ans % Zsy);
return 0;
}