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;
}

浙公网安备 33010602011771号