time limit per test

6 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The famous sculptor Cicasso is a Reberlandian spy!

These is breaking news in Berlandian papers today. And now the sculptor is hiding. This time you give the shelter to the maestro. You have a protected bunker and you provide it to your friend. You set the security system in such way that only you can open the bunker. To open it one should solve the problem which is hard for others but is simple for you.

Every day the bunker generates a codeword s. Every time someone wants to enter the bunker, integer n appears on the screen. As the answer one should enter another integer — the residue modulo 109 + 7 of the number of strings of length n that consist only of lowercase English letters and contain the string s as the subsequence.

The subsequence of string a is a string b that can be derived from the string a by removing some symbols from it (maybe none or all of them). In particular any string is the subsequence of itself. For example, the string "cfo" is the subsequence of the string "codeforces".

You haven't implemented the algorithm that calculates the correct answers yet and you should do that ASAP.

Input

The first line contains integer m (1 ≤ m ≤ 105) — the number of the events in the test case.

The second line contains nonempty string s — the string generated by the bunker for the current day.

The next m lines contain the description of the events. The description starts from integer t — the type of the event.

If t = 1 consider a new day has come and now a new string s is used. In that case the same line contains a new value of the string s.

If t = 2 integer n is given (1 ≤ n ≤ 105). This event means that it's needed to find the answer for the current string s and the value n.

The sum of lengths of all generated strings doesn't exceed 105. All of the given strings consist only of lowercase English letters.

Output

For each query of the type 2 print the answer modulo 109 + 7 on the separate line.

Example
Input
3
a
2 2
1 bc
2 5
Output
51
162626
Note

In the first event words of the form "a?" and "?a" are counted, where ? is an arbitrary symbol. There are 26 words of each of these types, but the word "aa" satisfies both patterns, so the answer is 51.

题意:

输入一个数q<=10^5,和一个字符串str,所有字符串都只包含小写英文字母

接下来有q个操作:

1 str 把原来的字符串替换成新的字符串

2 n

求:长度为n的,str为其的子串(不用连续)的字符串的个数 % (1e9+7)

保证所有输入的字符串的长度之和 <= 10^5

solution:

首先,这一道题在计数的时候要注意重复的情况

先计算所有,再减去重复的情况?这样太难算了

这道题相当于要填一个长度为n的字符串,使得包含str这个子串

考虑要避免重复,需要具有以下性质:

设长度为n的字符串为t

若t[i]是从str[j]这里拿的,t[i+k]是从str[j+1]拿的,则区间[i+1,i+k-1]这一段不能出现str[j+1]

则可以避免重复

令f(i,j)表示t填写了i个字符,此时指向str的第j个数的方案数

init:f(0,0) = 1

f(i,j) += f(k,j-1) * 25^(i-k-1)

明显复杂度太大了O(n^3)

但是从这一个递推我们发现,方案数只与str的长度len有关,与str的内容没有关系

这样的话,只要一个三元组(len,n,t)即可确定一个答案了

(其实是2元组(len,n),t是用来离线的时候确定第t个询问的)

则可以推出公式,对于一个三元组(len,n,t):

ans = sigma(C(x-1,len-1) * 25^(x-len) * 26^(n-x)), len <= x <= n

如果预处理:

jie[i] = i!

inv[i] = i!的关于mod的逆元 = qp(jie[i],mod-2)

则一次询问可以在O(n)的时间内得到答案,总复杂度O(n^2)还是不够

考虑离线,先len小到大,n小到大排序询问

则相同的len的元组都放在了一起

对于当前的len:

令f[i]表示3元组(len,i,t)的答案,把公式写成递推的形式:

f[i] = 0 ,i < len

f[i]= 1, i = len

f[i] = 26 * f[i-1] + C(i-1,len-1) * 25^(i-len)  (组合数C可以O(1))

则可以在O(n)的时间内对当前的len求出n=[1,MAXN-1]的答案,

则可以同时处理掉一大批询问了

对于len发生了变化的询问,只需要再更新一次f数组即可

因为有所有输入的字符串的长度之和 <= 10^5,所以最坏的情况下,输入的字符串的长度分别为

1,2,3,...,ma,则 (1+ma)*ma/2 <= 10^5,则ma的规模是在O(sqrt(n))的,

即是说,最多我们需要更新O(sqrt(n))次f数组,一次更新是O(n)的,所以总复杂度为

O(n^1.5)

这样的复杂度就可以接受了

ps:

刚开始没有预处理逆元,所以求组合数C要O(logn),总复杂度O(n^1.5 * logn),TLE了

代码:

   //File Name: cf666C.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年05月20日 星期五 14时28分15秒 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream> #define LL long long using namespace std; const int MAXN = + ;
const int MOD = (int)1e9 + ; LL jie[MAXN], p25[MAXN],inv[MAXN];
LL f[MAXN],ans[MAXN]; struct Query{
int len,n,t;
Query(int _len = ,int _n = ,int _t = ){
len = _len,n = _n,t = _t;
}
bool operator < (const Query & a) const{
if(len == a.len)
return n < a.n;
return len < a.len;
}
}q[MAXN]; LL qp(LL x,LL y){
LL res = ;
while(y){
if(y & ) res = res * x % MOD;
x = x * x % MOD;
y >>= ;
}
return res;
} void init(){
jie[] = ;
for(int i=;i<MAXN;i++)
jie[i] = jie[i-] * i % MOD;
p25[] = ;
for(int i=;i<MAXN;i++){
p25[i] = p25[i-] * % MOD;
}
for(int i=;i<MAXN;i++)
inv[i] = qp(jie[i],MOD - );
} LL get_c(LL x,LL y){
if(x < || x < y) return ;
if(y == || y == x) return ;
return jie[x] * inv[y] % MOD * inv[x-y] % MOD;
} char str[MAXN]; void update(int len,int N){
for(int i=;i<len;i++)
f[i] = ;
f[len] = ;
for(int i=len+;i<=N;i++){
f[i] = f[i-] * % MOD + get_c(i-,len-) * p25[i-len] % MOD;
f[i] %= MOD;
}
} void solve(int tot){
init();
sort(q,q+tot);
int pre = -;
for(int i=;i<tot;i++){
if(q[i].len == pre){
ans[q[i].t] = f[q[i].n];
}
else{
pre = q[i].len;
int now = i;
while(now < tot - && q[now+].len == q[now].len){
now++;
}
update(pre,q[now].n);
ans[q[i].t] = f[q[i].n];
}
}
for(int i=;i<tot;i++)
printf("%d\n",(int)ans[i]);
} int main(){
int op,len,tot = ;
scanf("%d",&op);
scanf("%s",str);
len = strlen(str);
for(int i=,u,n;i<=op;i++){
scanf("%d",&u);
if(u == ){
scanf("%s",str);
len = strlen(str);
}
else{
scanf("%d",&n);
q[tot] = Query(len,n,tot);
tot++;
}
}
solve(tot);
return ;
}

cf666 C. Codeword 组合数学 离线分块思想的更多相关文章

  1. cf666 C. Codeword 组合数学

    题解: 首先暴力很显然 f[i][j]表示到第i个位置,串匹配到j 这样每次是n^2的 我们假设每个位置匹配的第一个位置 然后从这个到上一个位置一定不能等于这个串的值 ans=simga{i,C(i- ...

  2. Codeforces Round #319 (Div. 1)C. Points on Plane 分块思想

                                                                              C. Points on Plane On a pl ...

  3. hdu6333 Harvest of Apples 离线+分块+组合数学(求组合数模板)

    Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K ...

  4. Codeforces Beta Round #80 (Div. 1 Only) D. Time to Raid Cowavans 离线+分块

    题目链接: http://codeforces.com/contest/103/problem/D D. Time to Raid Cowavans time limit per test:4 sec ...

  5. 莫队算法 sqrt(n)分块思想

    在此说一下本渣对莫队算法思想的一些浅薄理解 莫队算法的思想就是对真个区间的分块,然后按照每块来分别进行计算,这样最终的复杂度可以达到n*sqrt(n) 小Z的袜子是一道非常经典的题目.:题目链接htt ...

  6. ZOJ 1654 Place the Robots建图思维(分块思想)+二分匹配

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 AC一百道水题,不如AC一道难题来的舒服. 题意:一个n*m地图 ...

  7. PAT1057 stack(分块思想)

    1057 Stack (30分)   Stack is one of the most fundamental data structures, which is based on the princ ...

  8. HDOJ 4858 项目管理 ( 只是有点 莫队的分块思想在里面而已啦 )

    题目: 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 题意: 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! ...

  9. [BZOJ 2957]楼房重建(THU2013集训)(分块思想)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2957 分析: 首先明确问题,对于每栋楼房的斜率K=H/X,问题就是问有多少个楼房的K比前面所有 ...

随机推荐

  1. 局域网络ping不通

    描述:今天和老崔.老周去公司的新办公地点//相比临时的,十分高大上.当我们把两台台式电脑A.B装好了,网络设置也陪好了,确认能够上网,再装打印机的时候,发现搜索不到打印机的ip(打印机也是有自己的IP ...

  2. 【NOIP2010】关押罪犯

    一开始看错题了,然后怎么想都想不明白--原题: S 城现有两座监狱,一共关押着 N 名罪犯,编号分别为 1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲 ...

  3. Spring源码学习之:spring注解@Transactional

    在分析深入分析@Transactional的使用之前,我们先回顾一下事务的一些基本内容. 事务的基本概念 先来回顾一下事务的基本概念和特性.数据库事务(Database Transaction) ,是 ...

  4. docker学习3-虚拟网络模式

    一.虚拟机网络模式 在理解docker网络隔离前,先看下之前虚拟机里对网络的处理,VirtualBox中有4中网络连接方式: NAT Bridged Adapter Internal Host-onl ...

  5. Python学习笔记——文件

    1.文件只是连续的字节序列 open()内建函数是打开文件之门的钥匙 file_obj=open(file_name,access_mode='r/w/a,' buffering=-1) file_n ...

  6. 写window应用程序日志System.Diagnostics.EventLog.WriteEntry

    System.Diagnostics.EventLog.WriteEntry( MySource , Writing to event log. ); 可以写window应用程序日志 查看的地方:右击 ...

  7. javascript保留两位小数

      原文地址http://blog.csdn.net/he20101020/article/details/8503308   <script type="text/javascrip ...

  8. 019. Asp.net将SqlServer中的数据保存到xls/txt中

    using System; using System.Collections; using System.Configuration; using System.Data; using System. ...

  9. #linux包之tcpdump之tcpdump命令

    概述 man tcpdump 已阅 yum install tcpdump Downloading Packages:(1/2): libpcap-1.4.0-1.20130826git2dbcaa1 ...

  10. 数据接口管理工具 thx RAP

    RAP是数据接口管理工具.在开发时前端将请求转至RAP,由RAP提供模拟数据:而后端使用RAP测试接口的正确性.这样RAP就成为了开发过程中的强 依赖,进而确保接口文档的实时正确性.RAP采用JSON ...