• JZOJ6365. 【NOIP2019模拟2019.9.20】膜拜大会(fake)


    Description

    • 定义一次对于i位置的操作为a[l]+=a[i],a[r]+=a[i],a[i]=0,其中l和r为i的左边和右边位置(1的左为n,n的右为1),每一个位置只可以操作一次
    • 给定一个长度n的序列a,求长度为m的操作序列的个数,使得最终a[1]>=K。模998244353
      T<=5,n<=1e5,m<=n-2,ai<=1e9

    Solution

    • 由于m<=n-2的重要条件,所以如果一些位置对于1有贡献。那么一定是l-n按顺序传递,r-2按顺序传递。
    • 而1的选与不选以及跟2、n的位置关系决定了a[1]最后到1位置的贡献为2*a[1]、a[1]或0.
    • 所以我们可以分类讨论一下。
    • 我们可以设置两个指针l,r,也就是上面的意义。枚举l,另一边找到满足条件最终a[1]>=K的最小的r,这个r是单调不增的。然后再计算这一对l,r的方案数。注意到计算的时候可能还算到了l+1,r的方案数。
    • 为了避免算重,规定计算的是左边恰好为l,右边至少为r的方案数,所以对于“恰好”要容斥一下,即用l,r的方案减去l+1,r的方案(l,r方案计算的为至少l,r的)

    (1).1位置不选,对于位置1的贡献为sum(l,n)+sum(2,r)+a[1]。注意l,n和2,r的顺序已经确定了。
    (2).1位置选,再讨论1,2,n的位置(len1,len2分别表示(n-l+1)和(r-1))

    • 1,2,n——从m个选择(len1+len2+1)个,钦定最后一个为n,所以从(len1+len2)中选择(len1+1)个,钦定这里面最后一个为2。1可以出现在len1个中的任意一个。

    • 1,n,2——同上

    • 2,1,n——同样是钦定顺序,同上,不过钦定1出现在len1+1中的最后一个。

    • n,1,2——同上

    • 2,n,1——0

    • n,2,1——0

    • 1,n(无2)

    • 1,2(无n)

    • n,1——0

    • n,2——0

    • 注意K=0要特判。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define maxn 100005
    #define mo 998244353
    #define ll long long
    #define li(i) ((i==1)?n:i-1)
    #define ri(i) ((i==n)?1:i+1)
    using namespace std;
    
    int T,n,m,K,i,j,cnt,l,r,len1,len2;
    ll a[maxn],inv[maxn],jc[maxn],ijc[maxn],ans,s[maxn];
    
    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;
    }
    
    ll P(int n,int m){return (n<m)?0:jc[n]*ijc[n-m]%mo;}
    ll C(int n,int m){return (n<m)?0:jc[n]*ijc[m]%mo*ijc[n-m]%mo;}
    
    ll Sum(int l,int r){return s[r]-s[l-1];}
    ll F(int len1,int len2){
    	if (len1+len2>m) return 0;
    	return P(n-1-len1-len2,m-len1-len2)*C(m,len1)%mo*C(m-len1,len2)%mo;
    }
    ll G(int len1,int len2){
    	if (len1+len2+1>m) return 0;
    	return P(n-1-len1-len2,m-1-len1-len2)*C(m,len1+len2+1)%mo*C(len1+len2,len1+1)%mo*len1%mo;
    }
    ll H(int len1,int len2){
    	if (len1+len2+1>m) return 0;
    	return P(n-1-len1-len2,m-1-len1-len2)*C(m,len1+len2+1)%mo*C(len1+len2,len1+1)%mo;
    }
    ll S(int len){
    	return P(n-1-len-1,m-1-len)*C(m,len+1)%mo*len%mo;
    }
    
    int main(){
    	freopen("fake.in","r",stdin);
    	freopen("fake.out","w",stdout);
    	inv[0]=inv[1]=1; 
    	for(i=2;i<maxn;i++) inv[i]=inv[mo%i]*(mo-mo/i)%mo;
    	jc[0]=ijc[0]=1;
    	for(i=1;i<maxn;i++) jc[i]=jc[i-1]*i%mo,ijc[i]=ijc[i-1]*inv[i]%mo;
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d%d%d",&n,&m,&K);
    		for(i=1;i<=n;i++) scanf("%d",&a[i]);
    		if (K==0){
    			printf("1
    ");
    			continue;
    		}
    		for(i=1;i<=n;i++) s[i]=s[i-1]+a[i]; ans=0;
    		
    		for(r=1;r<=1+m;r++) if (s[r]>=K) 
    			{ans+=F(0,r-1)-F(1,r-1);break;}
    		for(l=n;n-l+1<=m;l--) {
    			len1=n-l+1,len2=r-1;
    			while (len1+len2>m||r>1&&Sum(l,n)+Sum(1,r-1)>=K)
    				r--,len2--;
    			if (Sum(l,n)+Sum(1,r)>=K) 
    				ans+=F(len1,len2)-F(len1+1,len2);
    		}
    		ans=(ans%mo+mo)%mo;
    		
    		if (m>=3){
    			r=m-1;
    			for(l=n;n-l+1<m-1;l--){
    				len1=n-l+1,len2=r-1;
    				while (len1+len2>=m||r-1>1&&Sum(l,n)+Sum(2,r-1)+a[1]*2>=K)
    					r--,len2--;
    				if (len2&&len1&&Sum(l,n)+Sum(2,r)+a[1]*2>=K){
    					ans+=G(len1,len2)-G(len1+1,len2);
    					ans+=G(len2,len1)-G(len2,len1+1);
    				}
    			}
    			r=m-1;
    			for(l=n;n-l+1<m-1;l--){
    				len1=n-l+1,len2=r-1;
    				while (len1+len2>=m||r-1>1&&Sum(l,n)+Sum(1,r-1)>=K)
    					r--,len2--;
    				if (len2&&len1&&Sum(l,n)+Sum(1,r)>=K) {
    					ans+=H(len1,len2)-H(len1+1,len2);
    					ans+=H(len2,len1)-H(len2,len1+1);
    				}
    			}
    			ans=(ans%mo+mo)%mo;
    		}
    		
    		if (m>=2){
    			for(r=2;r<=m;r++) if (Sum(1,r)>=K)
    				{ans+=S(r-1);break;}
    			for(l=n;n-l+1+1<=m;l--) if (Sum(l,n)+a[1]>=K)
    				{ans+=S(n-l+1);break;}
    		}
    		printf("%lld
    ",ans*ksm(P(n,m),mo-2)%mo);
    	}
    }
    
  • 相关阅读:
    [LeetCode] Construct Binary Tree from Inorder and Pretorder Traversal
    [LeetCode] Construct Binary Tree from Inorder and Postorder Traversal
    [LeetCode] Candy
    [LeetCode] Next Permutation
    [LeetCode] Permutation Sequence
    [LeetCode] Permutations II
    【转载pku】三十分钟掌握STL
    [LeetCode] Permutations
    【附论文】Facebook推面部识别软件 精准度高达97.25%
    【转载】limits.h
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090958.html
Copyright © 2020-2023  润新知