BZOJ4872 [Six Provinces Joint Examination 2017] Breaking up is a blessing [expectation dp]

topic

Zeit und Raum trennen dich und mich.
Time and space separate you from me. Mr. B is playing a game consisting of n lights and n switches. Given the initial states of these n lights, the subscripts are
positive integers from 1 to n. Each light has two states: on and off. We use 1 to indicate that the light is on, and 0 to indicate that the light is off.
The goal of the game is to turn off all the lights. But when the i-th switch is operated, the states of all the lights numbered as divisors of i (including 1 and i) will be
changed, that is, from on to off, or from off to on. Mr. B found this game difficult, so he thought of such a strategy, each time
a switch is randomly operated with equal probability until all the lights are turned off. This strategy requires a lot of operations, and Mr. B thought of such an optimization. If in the current situation,
all lights can be turned off by operating less than or equal to k switches, then he will no longer be random, and directly select the operation method with the smallest number of operations (this
strategy is obviously less than or equal to k steps) to operate these switches. Mr. B wants to know
the expected number of operations according to this strategy (that is, random operations first, and then less than or equal to k steps at the end, using the operation method with the smallest number of operations). This expectation may be very large, but Mr. B found that the factorial of this expectation multiplied by n must
be an integer, so he only needs to know the result of the integer modulo 100003.

input format

The first line contains two integers n, k.
The next line contains n integers, each 0 or 1, where the ith integer represents the initial condition of the ith lamp.
1 ≤ n ≤ 100000, 0 ≤ k ≤ n;

output format

Output one line, modulo 100003 for the expected number of operations multiplied by the factorial of n.

input sample

4 0

0 0 1 1

Sample output

512

answer

In order to minimize the number of operations, because the small cannot affect the large, then start from the large and close it. If you want to close it, you must close it, because there is no light to turn off the current light, so it is correct.
Such an enumeration is \(O( nlogn)\) , the number of steps required to preprocess the initial situation

Then expect dp to expect dp to be generally set
as the expected number of steps from the current state to the target state or the next state . \(i - 1\) operations to complete the expected number of operations required We have \(\frac{i}{n}\) probability that the operation is correct and \(\frac{n - i}{n}\ ) probability operation fails, at this time we are equivalent to one more operation to withdraw this failure, and return to \(f[i + 1]\)


So we have
\[f[i] = \frac{i}{n} + \frac{n - i}{n} * (1 + f[i + 1] + f[i])\]
simplifies to
\[f[i] = \frac{n}{i} + \frac{n - i}{i} * f[i + 1]\]
can be calculated by recursion to \ (f[i]\)

Since there are still \(k\) steps to start direct operation \(k\) steps to end, we make \(f[1...k] = 1\)
If the initial situation requires the number of steps to be \(m\)
\[ ans = \sum\limits_{i = 1}^{m} f[i]\]

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000,P = 100003;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    return out * flag;
}
int f[maxn],shut[maxn],a[maxn],inv[maxn],n,k,need;
int main(){
    n = read(); k = read();
    REP(i,n) a[i] = read();
    for (int i = n; i; i--){
        for (int j = i + i; j <= n; j += i)
            if (shut[j]) a[i] ^= 1;
        if (a[i]) shut[i] = true,need++;
    }
    inv[0] = inv[1] = 1;
    for (int i = 2; i <= n; i++) inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
    f[n] = 1;
    for (int i = n - 1; i; i--){
        f[i] = (1ll * n * inv[i] % P + 1ll * (n - i) * inv[i] % P * f[i + 1] % P) % P;
    }
    for (int i = 1; i <= k; i++) f[i] = 1;
    int ans = 0;
    for (int i = 1; i <= need; i++) ans = (ans + f[i]) % P;
    for (int i = 1; i <= n; i++) ans = 1ll * ans * i % P;
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324980731&siteId=291194637