您的位置:首页 > 财经 > 金融 > 牛客周赛 小红的数组回文值

牛客周赛 小红的数组回文值

2024/12/23 12:33:02 来源:https://blog.csdn.net/qq_74190237/article/details/142092852  浏览:    关键词:牛客周赛 小红的数组回文值

原题链接:F-小红的数组回文值

题意:给长度为n的数组,求这个数组的任意子序列的回文值总和,回文值定义为一个子序列应该元素相同,但是不相同的位置数量。

思路:范德蒙恒等式优化组合数。最暴力的思路是枚举出全部的子序列,然后暴力的计算回文值,但是明显会超时。从算贡献的角度来思考,对于每一对不相同的元素可以计算出这一对对全部子序列的贡献,例如说 i,j这二个位置不相同,如果它们在同一个子序列里面,就是在[1,i-1]和[j+1,n],这二个区间里面选择相同数量的数,再在[i+1,j-1]这个区间里面随便的取数,那么就可以的到答案的组合数公式。\sum_{i=1}^{n} \sum_{j=i}^{n}\sum_{k=0}^{min(i-1,n-j)}(\binom{i-1}{k}*\binom{n-j}{k}*2^{j-i-1}),根据范德蒙恒等式的性质,\sum_{i=0}^{k}(\binom{n}{k}*\binom{m}{k})=\binom{n+m}{k},所以答案就是\sum_{i=1}^{n} \sum_{j=i}^{n}(\binom{i-1+n-j}{min(i-1,n-j)}*2^{j-i-1})

//冷静,冷静,冷静
//调不出来就重构
//#pragma GCC optimize(2)
//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define count2(x) __builtin_popcountll(x)
#define is2(x) __builtin_ffsll(x)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1000000007;
ll p[N],fact[N],infact[N];
ll ksm(ll a,ll b)
{ll ans=1;do{if(b&1)ans*=a;a*=a;b>>=1;a%=mod;ans%=mod;}while(b);return ans;
}
ll C(ll a,ll b)
{return fact[a]%mod*infact[b]%mod*infact[a-b]%mod;
}
void Jiuyuan()
{ll n;cin>>n;fact[0]=infact[0]=1;for(int i=1;i<=n;i++){fact[i]=i*fact[i-1];fact[i]%=mod;infact[i]=ksm(i,mod-2)*infact[i-1];infact[i]%=mod;}for(int i=1;i<=n;i++){cin>>p[i];}ll ans=0;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){if(p[i]!=p[j]){ans=ans+(C(i-1+n-j,min(i-1ll,n-j))%mod*ksm(2,j-i-1)%mod)%mod;ans%=mod;}}}cout<<ans<<endl;
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll T=1;
//	cin>>T;while(T--){Jiuyuan();}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com