移言丁真:Unavoided linyue 题解
这种题当然要把括号序转化成格路啦!(如果你没见过这个操作,建议换道题做)
将左括号视为向上走,右括号视为向下走,那么容易发现:
最终括号串的权值只和它的
所以说,我们想求出长串
现在我们只要对于每个串快速求出它的
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cassert>
#define mod 1000000007
#define inv2 500000004
#define int long long
#define add(a,b) (a+=(b),a>=mod?a-=mod:0)
#define neg(x) ((x)&1?mod-1:1)
#define Q(a,b) C((a)+(b)-1,(b)-1)
using namespace std;
int fac[4007693],ifac[4007693];
int C(int n1,int m1){
if(m1<0||m1>n1)return 0;
return fac[n1]*ifac[m1]%mod*ifac[n1-m1]%mod;
}
inline int qpow(int n1,int n2){
int n3=n1,n4=1;
while(n2){
if(n2&1)n4*=n3,n4%=mod;
n3*=n3,n3%=mod;n2>>=1;
}return n4;
}
inline int mut(initializer_list<int> arg){
int ret=1;
for(auto i:arg)ret*=i,ret%=mod;
return ret;
}
int m,n,l[4076930],cnt,ans,ca[4076930],ck[4076930],r[4076930];
signed main(){
fac[0]=1;for(int i=1;i<=4001010;i++)fac[i]=fac[i-1]*i%mod;
ifac[4001010]=qpow(fac[4001010],mod-2);for(int i=4001010;i>=1;i--)ifac[i-1]=ifac[i]*i%mod;
scanf("%lld",&m);
for(int i=1;i<=m;i++)scanf("%lld",l+i),n+=l[i],r[l[i]]++;
for(int i=0;i<=n;i++)ca[i]=1;
for(int i=1;i<=n;i++){
if(r[i]==0)continue;
ck[0]=1;for(int j=1;j+j<=i;j++)ck[j]=(ck[j-1]+C(i,j))%mod;
// for(int j=0;j+j<=i;j++)printf("%lld ",ck[j]);printf("\n");
int p2=qpow(2,i),ip2=qpow(p2,mod-2);
for(int j=0;j+j<=i;j++){
if(i&1)ca[j]=ca[j]*qpow((p2-2*(i/2-1>=j?ck[i/2-j-1]:0)+2*mod)%mod*ip2%mod,r[i])%mod;
else ca[j]=ca[j]*qpow((p2-(i/2-1>=j?ck[i/2-j-1]:0)-(i/2-2>=j?ck[i/2-j-2]:0)+2*mod)%mod*ip2%mod,r[i])%mod;
}
}
// for(int i=0;i<=n;i++)printf("%lld ",ca[i]*qpow(2,n)%mod);printf("\n");
for(int i=n;i>=1;i--)add(ca[i],mod-ca[i-1]);
// for(int i=0;i<=n;i++)printf("%lld ",ca[i]*qpow(2,n)%mod);printf("\n");
for(int i=1;i<=n;i++)ans=(ans+ca[i]*i*2)%mod;
// printf("%lld\n",ans*qpow(2,n)%mod);
for(int i=1;i<=n;i++){
if(r[i]==0)continue;
int cur=0;for(int j=0;j<=i;j++)cur+=max(i-j*2,j*2-i)*C(i,j)%mod;
ans=(ans+mut({r[i],cur%mod,qpow(inv2,i)}))%mod;
}
// printf("%lld\n",ans*qpow(2,n)%mod);
ans=(n-ans+mod)*inv2%mod;
// printf("%lld\n",ans*qpow(2,n)%mod);
printf("%lld",ans);
}
"相关链接"