题面

Description

用m种字母构造一个长度为n的字符串,如果一个字符串的字母重组后可以形成一个回文串则该串合法,问随机构成的长为n的字符串的合法子串数目期望值.

Input

第一行一整数T表示用例组数,每组用例输入两个整数n,m(1≤n,m≤2000).

Output

问构成的字符串的合法子串数目期望值,结果乘m^n后模10^9+7.

题解

这是一道很好的练指数型母函数的题。

万幸它乘了个m^n,刚好把期望中的m^-n消去了。

考虑到合法字串的特征,它必须最多只有一种字母出现奇数次,其余出现偶数次,那我们分子串长度为奇偶(即,是否有字母出现奇数次)两种情况讨论。

奇的生成函数:

二项式展开:

最终的答案还要考虑其在母串中的出现次数

偶的生成函数:

二项式展开:

最终的答案考虑其在母串中的出现次数

把组合数和幂都预处理,最终复杂度

CODE

大常数TLE的代码QAQ

#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>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
#define LL long long
#define MAXN 105
#define rg register
#define DB double
using namespace std;
inline int read() {
int f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
int mod = 1000000007ll;
inline int qkpow(int a,int b) {
int res = 1;
while(b) {
if(b&1) res = 1ll*res*a % mod;
a = 1ll*a*a % mod;
b>>=1;
}
return res % mod;
}
int n,m,q,i,j,s,o,k,t;
int c[2005][2005];
int po[4010][2005];
int dp[2005],inv2 = qkpow(2,mod-2),inv2m[2005];
bool f[2005];
inline int POW(int i,int j) {
return po[i + 2000][j];
}
int main() {
c[0][0] = 1ll;inv2m[0] = 1ll;
for(rg int i = 1;i <= 2000;++ i) {
c[i][0] = c[i][i] = 1ll;
for(rg int j = 1;j < i;++ j) c[i][j] = (0ll + c[i-1][j]+c[i-1][j-1]) % mod;
inv2m[i] = (LL)inv2m[i-1]*inv2%mod;
}
for(rg int i = 0;i <= 4002;++ i) {
po[i][0] = 1ll;
for(rg int j = 1;j <= 2000;++ j) {
po[i][j] = ((LL)po[i][j-1]*(i-2000ll) + mod) % mod;
}
}
rg int T = read();
while(T--) {
n = read();m = read();
int AS = 0;
for(rg int i = 1;i <= n;++ i) {
if(i&1) {
int ans = (LL)inv2m[m] * (n - i + 1ll) % mod * POW(m,n-i) % mod * m % mod;
int ans2 = 0;
for(rg int j = 0;j < m;++ j) {
ans2 = (0ll+ans2 + mod + (POW((j<<1)+2-m,i) + mod - POW((j<<1)-m,i) + mod) * c[m-1][j] % mod) % mod;
}
ans = (LL)ans * ans2 % mod;
AS = (0ll + AS + mod + ans) % mod;
}
else {
int ans = (LL)inv2m[m] * (n - i + 1ll) % mod * POW(m,n-i) % mod;
int ans2 = 0;
for(rg int j = 0;j <= m;++ j) {
ans2 = (0ll+ans2 + mod + ((LL)POW((j<<1)-m,i) + mod) * c[m][j] % mod) % mod;
}
ans = (LL)ans * ans2 % mod;
AS = (0ll + AS + mod + ans) % mod;
}
}
printf("%d\n",AS);
}
return 0;
}

HDU 5362 Just A String 指数型母函数的更多相关文章

  1. HDU 2065 “红色病毒”问题 --指数型母函数

    这种有限制的类棋盘着色问题一般可以用指数型母函数来解决,设Hn表示这样的着色数,首先H0=1,则Hn等于四个字母的(A,B,C,D)的多重集合的n排列数,其中每个字母的重数是无穷,且要求A,C出现的次 ...

  2. 2015 Multi-University Training Contest 6 hdu 5362 Just A String

    Just A String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  3. 母函数 <普通母函数(HDU - 1028 ) && 指数型母函数(hdu1521)>

    给出我初学时看的文章:母函数(对于初学者的最容易理解的) 普通母函数--------->HDU - 1028 例题:若有1克.2克.3克.4克的砝码各一 枚,能称出哪几种重量?各有几种可能方案? ...

  4. 排列组合 HDU - 1521 -指数型母函数

    排列组合 HDU - 1521 一句话区分指数型母函数和母函数就是 母函数是组合数,指数型母函数是排列数 #include<bits/stdc++.h> using namespace s ...

  5. hdu1521 指数型母函数

    排列组合 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. hdu1521:排列组合---指数型母函数

    题意: n种元素,每种有 ni个,选出 m 个的排列有多少种 题解: 指数型母函数的裸题 x^n 项的系数为  an/n!.... 代码如下: #include <iostream> #i ...

  7. 【指数型母函数+非递归快速幂】【HDU2065】"红色病毒"问题

    大一上学完数分上后终于可以搞懂指数型母函数了.. 需要一点关于泰勒级数的高数知识 题目在此: "红色病毒"问题 Time Limit: 1000/1000 MS (Java/Oth ...

  8. 【指数型母函数】hdu1521 排列组合

    #include<cstdio> #include<cstring> using namespace std; int n,m,jiecheng[11]; double a[1 ...

  9. hdu1521 排列组合 指数型母函数模板题

    排列组合 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. 【视频】k8s套娃开发调试dapr应用 - 在6月11日【开源云原生开发者日】上的演示

    这篇博客是在2022年6月11日的[开源云原生]大会上的演讲中的演示部分.k8s集群套娃(嵌套)是指在一个k8s的pod中运行另外一个k8s集群,这想法看上去很疯狂,实际上非常实用. k8s集群套娃( ...

  2. 『忘了再学』Shell流程控制 — 33、if条件判断语句(一)

    目录 1.单分支if条件语句 2.双分支if条件语句 (1)示例1 (2)示例2 什么是流程控制? 普通理解:Shell编写的程序是顺序执行的,也就是说第一命令先执行,然后接着执行第二条命令,然后再下 ...

  3. 1.2 操作系统的第二个功能——并发功能 -《zobolの操作系统学习札记》

    1.2 操作系统的第二个功能--并发功能 目录 1.2 操作系统的第二个功能--并发功能 问1:什么是并发功能?并发功能是必要的吗? 问2:并发功能必须要求拥有多核CPU吗? 问3:多核CPU和单核C ...

  4. WPF中Popup控件的使用

    一.Popup控件的主要属性 Popup表示具有内容的弹出窗口,其主要属性为: Child:获取或设置 Popup控件的内容. IsOpen:获取或设置一个值,该值指示Popup 是否可见 Place ...

  5. BUUCTF-[BJDCTF2020]藏藏藏

    [BJDCTF2020]藏藏藏 打开图片发现存在压缩包,使用foremost分离一下. 得到压缩包,直接可以解压. 解码一下就可以得到flag

  6. jieba分词的功能和性能分析

    jieba分词问题导引 用户词典大小最大可以有多大 用户词典大小对速度的影响 有相同前缀和后缀的词汇如何区分 对比百度分词的API 问题一:词典大小 从源码大小分析,整个jieba分词的源码总容量为8 ...

  7. 修改windows字符集

    手动 临时修改cmd默认字符集(代码页) chcp xxxx 自动<打开cmd后应该自动运行dhcp 65001,临时设置为utf-8> D:\Develope\apache-tomcat ...

  8. 反向传播神经网络(BP)

    实验部分: ①输入.输出矢量及问题的阐述 由题意输入变量取值范围为e={-2,-1,0,1,2}和ec={-2,-1,0,1,2},则输入矢量有25种情况,分别如下所示: 则由T=int((e+ec) ...

  9. Dapr v1.8 正式发布

    Dapr是一套开源.可移植的事件驱动型运行时,允许开发人员轻松立足云端与边缘位置运行弹性.微服务.无状态以及有状态等应用程序类型.Dapr能够确保开发人员专注于编写业务逻辑,而不必分神于解决分布式系统 ...

  10. 【一知半解】synchronied

    synchronized是什么 synchronized是java同步锁,同一时刻多个线程对同一资源进行修改时,能够保证同一时刻只有一个线程获取到资源并对其进行修改,因此保证了线程安全性. synch ...