ARC 120 F Wine Thief 题解

ARC 120 F Wine Thief 题解

考虑每一个位置的贡献。

首先求合法方案数就是\({n-k+1\choose k}\)

但是每一个位置的贡献不相等,所以不好计算。

考虑把序列首位相连形成环,并在最后一个位置加上一个位置。

则方案就是所有可行方案减去选择了最后一个的方案。

时间复杂度为\(O(N)\)

/**
 *    author:  gary
 *    created: 28.10.2021 19:52:20
**/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define rep(a,b) for(int a=0;a<b;++a)
#define LL long long
#define PB push_back
#define POB pop_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
namespace combination
{
    const int MOD=998244353;
    const int MAXN=700000;
    int fact[MAXN+1],ifact[MAXN+1];
    int quick(int k1,int k2){
		int k3=1;for(;k2;k2>>=1,k1=1LL*k1*k1%MOD)if(k2&1)k3=1LL*k3*k1%MOD;return k3;
	}
    int inv(int A){return quick(A,MOD-2);}
    void genmath(){
        fact[0]=1;
        rb(i,1,MAXN) fact[i]=1ll*fact[i-1]*i%MOD;
        ifact[MAXN]=inv(fact[MAXN]);
        // cout<<fact[MAXN]<<endl;
        rl(i,MAXN-1,0) ifact[i]=1ll*ifact[i+1]*(i+1)%MOD;
    }
    int comb(int A,int B){
        if(A<B) return 0;
        return 1ll*fact[A]*ifact[B]%MOD*ifact[A-B]%MOD;
    }
    void add(int &A,int B){
        A+=B;
        if(A>=MOD) A-=MOD;
    }
    void sub(int &A,int B){
        A+=MOD-B;
        if(A>=MOD) A-=MOD;
    }
} // namespace combination
using namespace combination;
int b[MAXN],a[MAXN];
int calcline(int len,int k){
    return comb(len-k+1,k);
}
int calc(int len,int k){
    int ans=0;
    ans=2ll*calcline(len-3,k-1)%MOD;
    add(ans,calcline(len-2,k));
    return ans;
}
void solve(int l,int r,int k,bool ty){
    if(k==0) return ;
    int len=r-l+1;
    if(k>(len+1)/2) return ;
    if(len==1){
        if(ty){
            add(b[l],1);
            sub(b[r+1],1);
        }
        else{
            sub(b[l],1);
            add(b[r+1],1);
        }
        return ;
    }
    if(len==2){
        if(ty){
            add(b[l],1);
            sub(b[r+1],1);
        }
        else{
            sub(b[l],1);
            add(b[r+1],1);
        }
        return ;
    }
    int tmp=calc(len+1,k);
    tmp=1ll*k*tmp%MOD*inv(len+1)%MOD;
    if(ty){
        add(b[l],tmp);
        sub(b[r+1],tmp);
    }
    else{
        sub(b[l],tmp);
        add(b[r+1],tmp);
    }
    solve(l+1,r-1,k-1,ty^1);
}
int main(){
    genmath();
    int n,k,d;
    scanf("%d%d%d",&n,&k,&d);
    rb(i,1,n) scanf("%d",&a[i]);
    solve(1,n,k,1);
    rb(i,1,n) add(b[i],b[i-1]);
    int ans=0;
    rb(i,1,n) add(ans,1ll*a[i]*b[i]%MOD);
    cout<<ans<<endl;
    return 0;
}
posted @ 2021-10-28 20:35  WWW~~~  阅读(84)  评论(0)    收藏  举报