[2019.9.4] NOIP2019 Analog B (desired linearity)

Subject description:

\(1<=n,ai<=5*10^5\)

answer:

I mentally I would not expect linearity.

Set \ (E (a [i] ) \) represents the number of i-th desired to be subtracted.

\ (E (a [1]) = a [1] \)

Not difficult to find \ (E (a [i] ) (i> 1) \) between independently of each other, in fact, it's hard.

Consider two fixed, they are two options as to the probability, choose to ignore the other on just fine.

Then only consider \ (n = 2 \) case, the direct violence enumeration \ (a [1] \) at the end \ (a [i] \) there are several, by a \ (1 \ over 2 \ ) several parties and the number of combinations, the following formula:
\ (= a [I] - \ sum_ {I} = 0 {^ a [I] -1 C_ {a} [. 1] ^ {-1} + I a [i] -1} * { 1 \ over2} ^ {a [1] + i} * (a [i] -i) \)

The method may be used to sequentially obtain recursive \ (a [i] = 1,2,3 ... \) answers.

Time complexity: \ (O (n-+ max (A)) \)

Code:

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i <  B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int mo = 323232323;

ll ksm(ll x, ll y) {
    ll s = 1;
    for(; y; y /= 2, x = x * x % mo)
        if(y & 1) s = s * x % mo;
    return s;
}

const ll ni2 = ksm(2, mo - 2);

const int N = 1e6 + 5;

int n, a[N];

ll fac[N], nf[N], a2[N];

void build(int n) {
    fac[0] = 1; fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
    nf[n] = ksm(fac[n], mo - 2); fd(i, n, 1) nf[i - 1] = nf[i] * i % mo;
    a2[0] = 1; fo(i, 1, n) a2[i] = a2[i - 1] * ni2 % mo;
}

ll C(int n, int m) {
    return fac[n] * nf[m] % mo * nf[n - m] % mo;
}

ll f[N], g[N];

int main() {
    freopen("b.in", "r", stdin);
    freopen("b.out", "w", stdout);
    scanf("%d", &n);
    fo(i, 1, n) scanf("%d", &a[i]);
    build(1e6 + 2);
    fo(i, 0, 5e5) {
        if(i) f[i] = f[i - 1], g[i] = g[i - 1];     
        f[i] = (f[i] + a2[a[1] + i] * C(a[1] + i - 1, i)) % mo;
        g[i] = (g[i] + a2[a[1] + i] * C(a[1] + i - 1, i) % mo * i) % mo;
    }
    ll ans = a[1];
    fo(i, 2, n) {
        ans += a[i];
        ans -= (f[a[i] - 1] * a[i] - g[a[i] - 1]) % mo;
    }
    ans = (ans % mo + mo) % mo;
    pp("%lld\n", ans);
}

Guess you like

Origin www.cnblogs.com/coldchair/p/11470313.html