【CF666C】Codeword

题意:一开始有一个字符串s,有m个事件,每个事件形如:

1.用一个新的字符串t来替换s
2.给出n,问有多少个长度为n的小写字母组成的字符串满足包含s作为其一个子序列?答案$\mod 10^9+7$

$m,n,\sum |t|\le 10^5$

题解:有一个结论:答案只与n和|s|有关,与s到底是什么无关。我们只考虑s在母串中第一次出现的位置。设$|s|=k$,假如s的每个字符出现的位置分别是$p_1p_2...p_k$,则对于$i\in [1,k]$,$(p_{i-1},p_i)$之间的字符都不能是$s_i$,所以这些位置都有25种可能。然后我们就可以将我们发现的结论形式化的写出来了。我们枚举$p_k$的位置,则有:

$ans=\sum\limits_{i=k}^{n}C_{i-1}^{k-1}\alpha^{n-i}(\alpha-1)^{i-k}$

但是如果我们每次都暴力计算的话复杂度难以接受。不过我们发现本质不同的|s|只有$\sqrt n$种,所以我们去重,然后将式子改写为:

$ans=\alpha^{n}\sum\limits_{i=k}^nC_{i-1}^{k-1}\alpha^{-i}(\alpha-1)^{i-k}$

我们对于每个|s|都预处理出后面那些东西,便可做到$O(1)$回答询问,时间复杂度$O(m\sqrt n)$。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=100010;
const ll P=1000000007;
int m,N,tot;
struct node
{
int n,len,org;
}p[maxn];
char str[maxn];
ll jc[maxn],ine[maxn],jcc[maxn],q[maxn],q1[maxn],qi[maxn],s[maxn],ans[maxn];
bool cmp(const node &a,const node &b)
{
return a.len<b.len;
}
inline ll c(int a,int b)
{
if(a<b) return 0;
return jc[a]*jcc[a-b]%P*jcc[b]%P;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
m=rd(),scanf("%s",str),N=100000;
int i,j,a=strlen(str),b;
for(i=1;i<=m;i++)
{
if(rd()==1) scanf("%s",str),a=strlen(str);
else b=rd(),p[++tot].len=a,p[tot].n=b,p[tot].org=tot;
}
ine[0]=ine[1]=jc[0]=jc[1]=jcc[0]=jcc[1]=1;
for(i=2;i<=N;i++) jc[i]=jc[i-1]*i%P,ine[i]=P-(P/i)*ine[P%i]%P,jcc[i]=jcc[i-1]*ine[i]%P;
for(q[0]=q1[0]=qi[0]=i=1;i<=N;i++) q[i]=q[i-1]*26%P,q1[i]=q1[i-1]*25%P,qi[i]=qi[i-1]*ine[26]%P;
sort(p+1,p+tot+1,cmp);
for(i=1;i<=tot;i++)
{
a=p[i].len,b=p[i].n;
if(a!=p[i-1].len)
{
memset(s,0,sizeof(s[0])*a);
for(j=a;j<=N;j++) s[j]=(s[j-1]+q1[j-a]*qi[j]%P*c(j-1,a-1))%P;
}
ans[p[i].org]=q[b]*s[b]%P;
}
for(i=1;i<=tot;i++) printf("%lld\n",ans[i]);
return 0;
}

【CF666C】Codeword 结论题+暴力的更多相关文章

  1. [codevs5578][咸鱼]tarjan/结论题

    5578 咸鱼  时间限制: 1 s  空间限制: 128000 KB   题目描述 Description 在广袤的正方形土地上有n条水平的河流和m条垂直的河流,发达的咸鱼家族在m*n个河流交叉点都 ...

  2. BZOJ_1367_[Baltic2004]sequence_结论题+可并堆

    BZOJ_1367_[Baltic2004]sequence_结论题+可并堆 Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 ...

  3. [BZOJ3609][Heoi2014]人人尽说江南好 结论题

    Description 小 Z 是一个不折不扣的 ZRP(Zealot Round-game Player,回合制游戏狂热玩家), 最近他 想起了小时候在江南玩过的一个游戏.     在过去,人们是要 ...

  4. 【uoj#282】长度测量鸡 结论题

    题目描述 给出一个长度为 $\frac{n(n+1)}2$ 的直尺,要在 $0$ 和 $\frac{n(n+1)}2$ 之间选择 $n-1$ 个刻度,使得 $1\sim \frac{n(n+1)}2$ ...

  5. 【uoj#175】新年的网警 结论题+Hash

    题目描述 给出一张 $n$ 个点 $m$ 条边的无向连通图,每条边的边权为1.对于每个点 $i$ ,问是否存在另一个点 $j$ ,使得对于任意一个不为 $i$ 或 $j$ 的点 $k$ ,$i$ 到 ...

  6. 【uoj#180】[UR #12]实验室外的攻防战 结论题+树状数组

    题目描述 给出两个长度为 $n$ 的排列 $A$ 和 $B$ ,如果 $A_i>A_{i+1}$ 则可以交换 $A_i$ 和 $A_{i+1}$ .问是否能将 $A$ 交换成 $B$ . 输入 ...

  7. 【bzoj4401】块的计数 结论题

    题目描述 给出一棵n个点的树,求有多少个si使得整棵树可以分为n/si个连通块. 输入 第一行一个正整数N,表示这棵树的结点总数,接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相 ...

  8. 【bzoj3997】[TJOI2015]组合数学 Dilworth定理结论题+dp

    题目描述 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...

  9. 【bzoj2079】[Poi2010]Guilds 构造结论题

    题目描述 Zy皇帝面临一个严峻的问题,两个互相抵触的贸易团体,YYD工会和FSR工会,他们在同一时间请求在王国各个城市开办自己的办事处.这里有n个城市,其中有一些以双向马路相连,这两个工会要求每个城市 ...

随机推荐

  1. 移动端适配问题px->rem方法

    移动端web页面适配问题 1.引入插件 github地址:https://github.com/re54k/mobileweb-utilities/blob/master/util/mobile-ut ...

  2. MySQL 连接不上本地数据库

    1.打开 DOS 窗口,输入 mysql 连接命令时,提示报错 Cannot connect to MySQL server on 'localhost' (10061),如下图: 2.上面问题原因 ...

  3. 【贪心】LIS @The 15th Zhejiang Provincial Collegiate Programming Contest E

    传送门 题意要你构造一个序列,使得该序列的每个位置上的最长上升子序列的长度能构成给定的序列. 构造序列的元素要求还要求满足给定的上下界 solution 我们可以把给出的最长上升子序列的长度按升序排列 ...

  4. 【最大公约数&链表】权值 @upcexam5921

    时间限制: 1 Sec 内存限制: 512 MB 题目描述 给定一个长为n的正整数序列Ai.对于它的任意一个连续的子序列{Al, Al+1, …, Ar},定义其权值W (l, r)为其长度与序列中所 ...

  5. GMA Round 1 极坐标的忧伤

    传送门 极坐标的忧伤 为什么你们不喜欢为我求导……——极坐标 极坐标的心意,想必已经传达到了,那么请为极坐标方程$r=t$(也写作$ρ=θ$)求导吧. 为了考验你的忠诚,你需要回答$r=t$在(0,$ ...

  6. pygame 笔记-5 模块化&加入敌人

    上一节,已经用OOP方法,把几个类抽象出来了,但是都集中在一个.py文件中,代码显得很冗长,这一节复用模块化的思想,把这个大文件拆分成几个小文件: 先把主角Player单独放到一个文件player.p ...

  7. oracle操作字符串:拼接、替换、截取、查找、长度、判断

    1.拼接字符串 1)可以使用“||”来拼接字符串 select '拼接'||'字符串' as str from dual 2)通过concat()函数实现 select concat('拼接', '字 ...

  8. 利用referer属性,记录百度搜索跳转参数

    从百度搜索结果跳转到指定链接前,百度会发送一些参数,可以利用referer属性,在本站访问时记录百度跳转来之前的一些参数. 利用百度跳转前参数,进行一些相关的seo优化. 目前所用到的一些参数说明如下 ...

  9. 基于ping++聚合支付进行微信红包开发

    1.微信方面的开发,一定要详细的阅读微信支付的开发文档. https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13 ...

  10. DBS-Function:f_GetPy

    ylbtech-SQL Server-Function:f_GetPy   A, 返回顶部 1.f_GetPy )) ) as begin ) ) collate Chinese_PRC_CI_AS, ...