E. Intercity Travelling(组合数)

题意

给出一个n,n个困难值,长度为n的直线距离,然后每个点可以休息,一旦休息困难值将从1开始。问困难值的期望*2^n-1

思路:

一共有2^n-1种情况,乘以期望,其实就是这么多种情况,每种情况的困难值的和
就可以分别计算每个位置的值被用了多少次
Ni表示a[i]被用的次数 N 1 = ∑ i = 0 n − 1 ( i + 1 ) ∗ C n − 1 i N1=\sum_{i=0}^{n-1}(i+1)*C_{n-1}^{i} N1=i=0n1(i+1)Cn1i
N 1 = 1 ∗ C n − 1 0 + 2 ∗ C n − 1 1 + 3 ∗ C n − 1 2 . . . . + n ∗ C n − 1 n − 1 N1=1*C_{n-1}^{0}+2*C_{n-1}^{1}+3*C_{n-1}^{2}....+n*C_{n-1}^{n-1} N1=1Cn10+2Cn11+3Cn12....+nCn1n1
C n − 1 i = C n − 1 n − 1 − i C_{n-1}^{i}=C_{n-1}^{n-1-i} Cn1i=Cn1n1i
N 1 = 1 ∗ C n − 1 n − 1 + 2 ∗ C n − 1 n − 2 + 3 ∗ C n − 1 n − 3 . . . . + n ∗ C n − 1 0 N1=1*C_{n-1}^{n-1}+2*C_{n-1}^{n-2}+3*C_{n-1}^{n-3}....+n*C_{n-1}^{0} N1=1Cn1n1+2Cn1n2+3Cn1n3....+nCn10
2 N 1 = ( n + 1 ) ∗ ∑ i = 0 n − 1 C n − 1 i = ( n + 1 ) ∗ 2 n − 1 2N1=(n+1)*\sum_{i=0}^{n-1}C_{n-1}^{i}=(n+1)*2^{n-1} 2N1=n+1i=0n1Cn1i=(n+1)2n1
N 1 = ( n + 1 ) ∗ 2 n − 2 N1=(n+1)*2^{n-2} N1=(n+1)2n2

那么N2就可以由N1递推出来,出现如果出现a[1]的后面一个点不休息,那么就会出现a[2],总共有n-1个点,其中紧靠着出现a[1]的一个点始终为0,实际上可计算的就变成n-2个点了,因此N2相当于将n用n-1代入N1就得到公式了
N 2 = ( n ) ∗ 2 n − 3 N2=(n)*2^{n-3} N2=(n)2n3
那么
N i = ( n + 2 − i ) ∗ 2 n − 1 − i Ni=(n+2-i)*2^{n-1-i} Ni=(n+2i)2n1i
最终的答案
a n s = ∑ i = 1 n N i ∗ a [ i ] ans=\sum_{i=1}^{n}Ni*a[i] ans=i=1nNia[i]

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=1e6+5;
const ll mod=998244353;
ll a[N];
ll mod_pow(ll x,ll n){
	if(n==-1)return mod_pow(2,mod-2); 
	ll res=1;
	while(n>0){
		if(n&1)res=res*x%mod;
		n>>=1;
		x=x*x%mod;
	}
	return res;
}
int main()
{
	int n;
	scanf("%d",&n);
	rep(i,1,n+1)
		scanf("%I64d",&a[i]);
	ll cnt=0;
	for(int i=1;i<=n;++i){
		cnt=(cnt+(n+2-i)*mod_pow(2,n-1-i)%mod*a[i]%mod)%mod;
	}
	
	printf("%I64d",cnt);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值