题目

原题目

点这里

简易题意

现定义一个合法的字符串满足将其打散并任意组合之后能够形成回文串。

给你 \(m\) 种字母,问随机构成长度为 \(n\) 的字符串的合法子串的个数期望

对于答案期望 \(E\) ,现要求输出 \(E\cdot m^n\pmod{1000000007}\) 的值。

思路及分析

首先发现答案的输出要求很怪——要求输出 \(E\cdot m^n\pmod{1000000007}\) 的值。

对其进行分析:

假如我们有 \(k\) 个合法子串,那么 \(E=\frac{k}{m^n}\) ,而答案为 \(E\cdot m^m=\frac{k}{m^n}m^n=k\) 。

换句话说,题目要求:

在用 \(m\) 种字符构造的长度为 \(n\) 的串中合法子串的个数,对其取模 \(10^9+7\) 之后输出。

考虑枚举子串长度 \(k\) ,思考如何构造母函数。


  • 对于 \(2\nmid k\) 的情况。

是一定有且仅有一种字符出现了奇数次,其余字符出现偶数次,那么其母函数就为

\[\left (\frac{e^x+e^{-x}}{2}\right )^{m-1}\cdot \frac{e^x+e^{-x}}{2}
\]

考虑选择 \(m\) 个字符中的 \(1\) 个,方案数为 \(C_m^1\) ,那么其真正的母函数为

\[C_m^1\cdot \left (\frac{e^x+e^{-x}}{2}\right )^{m-1}\cdot \frac{e^x+e^{-x}}{2}=m\cdot \left (\frac{e^x+e^{-x}}{2}\right )^{m-1}\cdot \frac{e^x+e^{-x}}{2}
\]

二项式展开,可得

\[m\cdot \left (\frac{e^x+e^{-x}}{2}\right )^{m-1}\cdot \frac{e^x+e^{-x}}{2}=m\cdot 2^{-m}\cdot \left( \sum_{i=0}^{m-1}C_{m-1}^ie^{(2i-m+2)x}-e^{(2i-m)x} \right)
\]

将 \(e^k\) 还原,可得原式为

\[m\cdot 2^{-m} \sum_{i=0}^{m-1}C_{m-1}^i\left( \sum_{j=0}^\infty \frac{(2i-m+2)^j-(2i-m)^j}{j!}x^j\right)
\]

那么,第 \(k\) 项的系数 \(a_k\) 的等式就为

\[a_k=m\cdot 2^{-m}\cdot \sum_{i=0}^{m-1} C_{m-1}^i \frac{(2i-m+2)^k-(2i-m)^k}{k!}
\]

由于我们最后还要乘以全排,即 \(k!\) ,所以 \(a_k\) 里面的 \(k!\) 可以直接消掉,即

\[a_k=m\cdot 2^{-m}\cdot \sum_{i=0}^{m-1} C_{m-1}^i[(2i-m+2)^k-(2i-m)^k]
\]

而我们还要考虑这个长度为 \(k\) 的合法子串在最大的长度为 \(n\) 的串中出现的次数,而剩下的 \(n-k\) 个位置都是随便取字符,所以最后我们要求的是

\[a_k\cdot m^{n-k}\cdot (n-k+1)
\]

这是长度为奇数的情况。


  • 对于 \(2\mid k\) 的情况。

这种情况下,所有的字符出现次数都为偶数次,所以母函数较好构造,为

\[\left ( \frac{e^x+e^{-x}}{2} \right )^m
\]

同理,将其大力展开,可得

\[2^{-m}\cdot \left ( \sum_{i=0}^{m}C_m^i\cdot e^{(2i-m)x} \right )
\]

将 \(e^{(2i-m)x}\) 还原,可得

\[2^{-m}\cdot \sum_{i=0}^{m}C_m^i\left ( \sum_{j=0}^\infty \frac{(2i-m)^j}{j!}x^j \right )
\]

所以,第 \(k\) 项系数 \(b_k\) 为

\[b_k=2^{-m}\sum_{i=0}^{m}C_m^i\frac{(2i-m)^k}{k!}
\]

因为我们最后乘以 \(k!\) ,所以 \(b_k\) 中的 \(k!\) 可以消掉,即

\[b_k=2^{-m}\sum_{i=0}^{m}C_m^i(2i-m)^k
\]

而我们最后要求

\[b_k\cdot m^{n-k}\cdot (n-k+1)
\]


代码

这是一发 TLE 的代码,但是我不想改了...

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks") #include<cstdio> #define rep(i,__l,__r) for(register int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(register int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair<int,int>
#define Endl putchar('\n')
// #define FILEOI
// #define int long long #ifdef FILEOI
#define MAXBUFFERSIZE 500000
inline char fgetc(){
static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
}
#undef MAXBUFFERSIZE
#define cg (c=fgetc())
#else
#define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
inline int qread(){
int x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
} const int MAXN=2000;
const int MOD=1e9+7; int C[MAXN+5][MAXN+5];
int inv2,inv2_fac[MAXN+5];
int Pow[MAXN*2+5][MAXN+5];
int n,m,T; inline int qkpow(int a,int n){
if(n<=MAXN)return Pow[a+2000][n];
int ret=1;
for(;n>0;n>>=1,a=1ll*a*a%MOD)if(n&1)ret=1ll*ret*a%MOD;
return ret;
} inline void init(){
rep(i,0,MAXN*2+2)rep(j,0,MAXN){
if(j==0)Pow[i][j]=1;
else Pow[i][j]=1ll*Pow[i][j-1]*(i-2000)%MOD;
}
inv2=qkpow(2,MOD-2);
inv2_fac[0]=1;
C[0][0]=1;
rep(i,1,MAXN){
inv2_fac[i]=1ll*inv2_fac[i-1]*inv2%MOD;
C[i][0]=C[i][i]=1;
rep(j,1,i){
C[i][j]=C[i-1][j-1]+C[i-1][j];
if(C[i][j]>MOD)C[i][j]-=MOD;
}
}
} int ans1,ans2,ans; signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
init();
qread(T);
while(T--){ans=0;
qread(n,m);
rep(k,1,n){
if(k&1){
ans1=1ll*inv2_fac[m]*(n-k+1)*qkpow(m,n-k+1)%MOD,ans2=0;
rep(i,0,m-1)ans2=(0ll+ans2+1ll*C[m-1][i]*(qkpow((i<<1)-m+2,k)-qkpow((i<<1)-m,k)))%MOD;
ans1=1ll*ans1*ans2%MOD;
}
else{
ans1=1ll*inv2_fac[m]*(n-k+1)*qkpow(m,n-k)%MOD,ans2=0;
rep(i,0,m)ans2=(0ll+ans2+1ll*C[m][i]*qkpow((i<<1)-m,k))%MOD;
ans1=1ll*ans1*ans2%MOD;
}
ans=(0ll+ans+1ll*ans1*2)%MOD;
if(ans<0)ans+=MOD;
else if(ans>MOD)ans-=MOD;
}
writc(ans,'\n');
}
return 0;
}

「题解」Just A String的更多相关文章

  1. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  4. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  5. 「题解」:$Six$

    问题 A: Six 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...

  6. 「题解」:$Smooth$

    问题 A: Smooth 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...

  7. 「题解」:Kill

    问题 A: Kill 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...

  8. 「题解」:y

    问题 B: y 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...

  9. 「题解」:x

    问题 A: x 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...

随机推荐

  1. set,get,setter

    JS对象属性中get/set与getter/setter是什么 2019-01-18 15:07:44 CHENKAI188 阅读数 686更多 分类专栏: JS修仙系列   版权声明:本文为博主原创 ...

  2. Python之xml读写

    遇到问题xml文件读写,没有子节点需要新建ChildNode. # -*- coding: utf-8 -*- import os import shutil import xml.dom.minid ...

  3. moment of 2019.08.15

    一件事,足以影响一个人的一生,准确的说,是两个人的人生轨迹. 人生中的遇见,有的是幸运,有的是不幸.2018.4的遇见,是我人生中的不幸,至少到目前为止,确实是不幸,从各个方面让我的生活不如以前. 如 ...

  4. 每天进步一点点------Nios II 的Run as hardware 中报错:Downloading ELF Process failed

    今天继续调试,又出现了新问题.在执行NIOS程序代码时,不能下载了:Pausing target processor: not responding. Resetting and trying aga ...

  5. C# RichTextBox实现背景透明

    这几天在做一个文本编辑器,要将RichTextBox的背景透明,但是发现C#的RichTextBox是不支持将背景设置为Transparent(透明). 网上找了好多方法,但都不行. 后来自己想了个办 ...

  6. codeforce 427 C. Checkposts(tarjan 强连通分量)

    题目链接:http://codeforces.com/contest/427/problem/C 题目大意是有n个junctions,这些junctions之间有m条道路,两两相连,现在在juncti ...

  7. js的全局变量与var关键字

    var a = '1'; 如果定义在函数外,就是全局变量.如果定义在函数内,就不是全局变量,只能在函数内调用. 但是:如果在函数内定义变量,没有加var关键字,默认表示该变量是全局的.

  8. python正则子组匹配

    子组匹配返回找到的第一个匹配项 []表示匹配列表中的任意一个,返回找到的第一个 这样可以发现如果要查找字母的话可以使用[a-z],返回找到的第一个字母 查找数字使用[0-9],返回找到的第一个数字相当 ...

  9. kbhit函数说明

    kbhit,用来检测键盘是否被敲击.所以就有了他的名字:keyboard hit 当键盘有按键被按下时,kbhit函数就会返回一个非0值. 当我们在写某个程序时,希望读入一些字符,但是又不能停在那里只 ...

  10. CTF_论剑场 名侦探柯南

    首先看一下是一个压缩包然后下载 解压后会发现一个图片和另一个压缩包 打开图片 发现是这个 用HxD分析一下这张图片通过搜索 zip jpg...... 然后会发现这张图片里有一个png 图片 所以判断 ...