NOIP2019 analog 2019.9.20] worship of the General Assembly (Social inclusion and exclusion tree, classification discussion)

Portal.

answer:


I really was not good at Category talk, the mentality is out collapse.

Noting \ (m <= n-2-\) , means that in addition to the position other than 1 can not be applied to a [1] twice.

Consider a ballpark:

If there is considered \ (X, X-1, ..., 2 \) (ordered) such, and does not appear either 1 or 2 appears to the left, then \ (a [1] = \ sum_ {i = 1 ^ XA} [I] \) .

Similarly, if there \ (Y, Y + 1, ..., n \) , and 1 or does not appear, or appears to the left of n, then the \ (a [1] = a [1] + \ sum_ {i = y Na ^} [I] \) .

Start a discussion:
1.1 does not appear, direct enumeration of x, y is determined to meet the biggest \ (SUM> = K \) , probably now required to be exactly x, y to be at least.

At least a good count, exactly, then at least consider the use of at least minus x x + 1.

2.1 appeared, only the right 1 2,, n either do not appear or appear to the left of 1, note that in this case \ (y-> n \) and will still be added to a [1], the same pieces For x, find the maximum of y, then we can list a limit tree, if \ (j \) must be \ (i \) to the left of, \ (Link (i, J) \) , according to CTS2019 krypton gold bracelet that tour title, the probability is \ (\ Prod {1 \ over SIZ} \) , multiplied by the total number of program is feasible on a number of programs.

3. The case of the 2, n interchanged method for finding similar.

4.1 appeared, and n 2 are 1 on the right, pay attention to this case, \ (a [1] \) is added twice, the same enumeration x, seeking the most of y, then list the restrictions tree, not found Outbound tree, there is a introverted side, then put the side directly to inclusion and exclusion.

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 = 998244353;

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 int N = 2e5 + 5;

int T, n, m, K;
ll a[N];

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

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

ll P(int n, int m) {
    return n < m || n < 0 || m < 0 ? 0 : fac[n] * nf[n - m] % mo;
}

ll p[N], q[N];

ll ans;

ll ca1(int x, int z) {
    return (x + z <= m) ? (C(m, x) * C(m - x, z) % mo * P(n - 1 - x - z, m - x - z) % mo) : 0;
}
void calc1() {
    int y = n + 1;
    fd(x, m + 1, 1) {
        while(y > 1 && p[x] + q[y] < K) y --;
        if(p[x] + q[y] < K) continue;
        int z = n - y + 1;
        ans += ca1(x - 1, z);
        ans -= ca1(x, z);
    }
    ans %= mo;
}

ll ca2(int x, int z) {
    if(x + z > m) return 0;
    return fac[m] * C(n - (x + z), m - (x + z)) % mo * nf[x - 2] % mo * nf[z + 1] % mo * ni[x + z] % mo;
}
void calc2() {
    int y = n + 1;
    fd(x, m, 2) {
        while(y > 1 && p[x] + q[y] < K) y --;
        if(p[x] + q[y] < K) continue;
        int z = n - y + 1;
        if(z > 0) {
            ans += ca2(x, z);
            ans -= ca2(x + 1, z);
        } else {
            n --;
            ans += ca2(x, z);
            ans -= ca2(x + 1, z);
            n ++;
            ans += ca2(x, 1);
            ans -= ca2(x + 1, 1);
        }
    }
}

void calc3() {
    int z = 1;
    fo(y, n - m + 1, n) {
        while(z < n && p[z] + q[y] < K) z ++;
        if(p[z] + q[y] < K) continue;
        int x = n - y + 2;
        if(z > 1) {
            ans += ca2(x, z - 1);
            ans -= ca2(x + 1, z - 1);
        } else {
            n --;
            ans += ca2(x, z - 1);
            ans -= ca2(x + 1, z - 1);
            n ++;
            ans += ca2(x, 1);
            ans -= ca2(x + 1, 1);
        }
    }
}

ll ca4(int x, int z) {
    if(x + z > m) return 0;
    ll sum = nf[z] * nf[x - 2] % mo * ni[x] % mo;
    sum = (sum - nf[z + 1] * nf[x - 2] % mo * ni[x + z] % mo + mo) % mo;
    return C(n - (x + z), m - (x + z)) * fac[m] % mo * sum % mo;
}

void calc4() {
    int y = n;
    fd(x, m, 2) {
        while(y > 1 && p[x] + q[y] + a[1] < K) y --;
        if(p[x] + q[y] + a[1] < K) continue;
        int z = n - y + 1;
        ans += ca4(x, z);
        ans -= ca4(x + 1, z);
    }
}

int main() {
    freopen("fake.in", "r", stdin);
    freopen("fake.out", "w", stdout);
    n = 2e5;
    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;
    fo(i, 1, n) ni[i] = ksm(i, mo - 2);
    for(scanf("%d", &T); T; T --) {
        scanf("%d %d %d", &n, &m, &K);
        fo(i, 1, n) scanf("%lld", &a[i]);
        if(K == 0) {
            pp("1\n"); continue;
        }
        q[n + 1] = p[0] = 0;
        fo(i, 1, n) p[i] = p[i - 1] + a[i];
        fd(i, n, 1) q[i] = q[i + 1] + a[i];
        ans = 0;
        calc1();
        calc2();
        calc3();
        calc4();
        ans = (ans % mo + mo) * ksm(P(n, m), mo - 2) % mo;
        pp("%lld\n", ans);
    }
}

Guess you like

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