题目分析:

从$\sum|S|$入手。共考虑$\sum|S|$个$f(t)$。所以我们要一个对于每个$f(t)$在$O(1)$求解的算法。不难想到是哈希。

然后考虑分裂和合并操作。一次合并操作要考虑合并点之前的$O(k)$个点向后衔接的哈希值。共$O(k^2)$。看似超时实则不然。一个串最多$O(nk)$个哈希结果,所以均摊入手。

对于分裂和重合并不能均摊,所以多了一个$O(ck^2)$。

这题的合并和分裂只和合并点和分裂点有关,而这个信息是给出的,所以不需要额外使用数据结构维护结果。

时间复杂度$O(nk+mk+ck^2+\sum |s|)$

代码:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std; const int maxsz = ;
const int maxn = ;
const int mod = ;
const int hmod1 = ;
const int hmod2 = ; int n,m,maxx;
int a[maxn],pts[maxn];
int ans[maxn],Num,nouse[],nuse[];
int hsh[hmod1+],Nxt[maxn*],real[maxn*],val[maxn*],hnum; struct query{ int cas;string str; int l,r; }Q[maxn]; int global = ; struct linktable{int pre[maxn>>],nxt[maxn>>];}T; void in(int &x){
char ch = getchar();
while(ch > '' || ch < '') ch = getchar();
while(ch <= '' && ch >= '') x = x*+ch-'',ch = getchar();
} void readstring(string &str){
char ch = getchar();
while(ch > '' || ch < '') ch =getchar();
while(ch <= '' && ch >= '') str.push_back(ch),ch=getchar();
} void read(){
in(n),in(m);
for(int i=;i<=n;i++) {in(a[i]);}
for(int i=;i<=m;i++){
in(Q[i].cas);
if(Q[i].cas == ) in(Q[i].l),in(Q[i].r);
else if(Q[i].cas == ) in(Q[i].l);
else {readstring(Q[i].str),in(Q[i].l);Q[i].r = ++Num;maxx = max(maxx,Q[i].l);}
}
} int imnum[],numnum; void Add_hash(int a1,int a2,int dr){
int p1 = hsh[a1];
while(true) {
if(real[p1] == a2) {val[p1]+=dr;return;}
if(Nxt[p1]) p1 = Nxt[p1];
else break;
}
hnum++; if(p1) Nxt[p1] = hnum;
p1 = hnum; val[p1] = ; real[p1] = a2;
if(!hsh[a1]) hsh[a1] = p1;
} void buildnew(int lft,int rgt,int dr){
numnum = ;int now = lft;
while(true){
if(numnum == maxx-) break;
imnum[++numnum] = a[now];
if(T.pre[now]) now = T.pre[now];
else break;
}
now = rgt;long long um = ,vm = ;
for(int i=;i<=numnum;i++){
um = (1ll*nouse[i-]*imnum[i]+um)%hmod1;
vm = (1ll*nuse[i-]*imnum[i]+vm)%hmod2;
long long r1 = um,r2 = vm;
for(int j=i+,jj=rgt;j<=maxx;j++){
r1 = (r1*+a[jj])%hmod1; r2 = (r2*+a[jj])%hmod2;
Add_hash(r1,r2,dr); if(!T.nxt[jj])break; jj = T.nxt[jj];
global++;
}
}
} void link(int lft,int rgt){
buildnew(lft,rgt,);
T.nxt[lft] = rgt; T.pre[rgt] = lft;
} void cut(int place){
buildnew(place,T.nxt[place],-);
T.pre[T.nxt[place]] = ; T.nxt[place] = ;
} int COUNT(int alpha,int beta){
int fw = ;
for(int i=hsh[alpha];i;i=Nxt[i]){
if(real[i] != beta) continue;
fw += val[i];
}
return fw;
} void work(){
for(int i=;i<=n;i++) nouse[a[i]]++;
for(int i=;i<=m;i++){
if(Q[i].cas != || Q[i].l != ) continue;
int fw = ; for(int j=;j<Q[i].str.length();j++){fw = (1ll*fw*nouse[Q[i].str[j]-''])%mod;}
ans[Q[i].r] = fw;
}
memset(nouse,,sizeof(nouse)); nouse[] = ;nuse[] = ;
for(int i=;i<=;i++) nouse[i] = (nouse[i-]*10ll)%hmod1,nuse[i] = (nuse[i-]*10ll)%hmod2; for(int i=;i<=m;i++){
if(Q[i].cas == ) link(Q[i].l,Q[i].r);
else if(Q[i].cas == ) cut(Q[i].l);
else{
if(Q[i].l == ) continue;
int fw = ;long long hres1=,hres2 = ;
for(int j=;j<Q[i].l;j++){
hres1 = hres1*+Q[i].str[j]-'';
hres2 = hres2*+Q[i].str[j]-'';
hres1 %= hmod1; hres2 %= hmod2;
}
fw = (1ll*fw*COUNT(hres1,hres2))%mod;
for(int j=Q[i].l;j<Q[i].str.length();j++){
hres1 -= ((Q[i].str[j-Q[i].l]-'')*nouse[Q[i].l-])%hmod1;
hres1 += hmod1; hres1 %= hmod1;
hres2 -= ((Q[i].str[j-Q[i].l]-'')*nuse[Q[i].l-])%hmod2;
hres2 += hmod2; hres2 %= hmod2;
hres1 = (hres1*+Q[i].str[j]-'');hres1 %= hmod1;
hres2 = (hres2*+Q[i].str[j]-'');hres2 %= hmod2;
fw = (1ll*fw*COUNT(hres1,hres2))%mod;
}
ans[Q[i].r] = fw;
}
}
for(int i=;i<=Num;i++) printf("%d\n",ans[i]);
} int main(){
read();
work();
return ;
}

洛谷3823 [NOI2017] 蚯蚓排队 【哈希】的更多相关文章

  1. 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】

    题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...

  2. P3823_[NOI2017]蚯蚓排队 哈希+脑子

    之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...

  3. 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)

    Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...

  4. BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...

  5. [NOI2017]蚯蚓排队 hash

    题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...

  6. 【题解】洛谷P2827 [NOIP2016TG] 蚯蚓(优先队列)

    题目来源:洛谷P2827 思路 阅读理解题 一开始以为是裸的优先队列而已 但是发现维护一个切开并且其他的要分别加上一个值很不方便 而且如果直接用优先队列会TLE3到4个点 自测85分 所以我们需要发现 ...

  7. 洛谷3825 [NOI2017]游戏 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...

  8. 【题解】洛谷P1966 [NOIP2013TG] 火柴排队(树状数组+逆序对)

    次元传送门:洛谷P1966 思路 显然在两排中 每排第i小的分别对应就可取得最小值(对此不给予证明懒) 所以我们只在意两排的火柴是第几根 高度只需要用来进行排序(先把两个序列改成有序的方便离散化) 因 ...

  9. 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】

    UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...

随机推荐

  1. Item 16: 让const成员函数做到线程安全

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果我们在数学领域里工作,我们可能会发现用一个类来表示多项式会很方 ...

  2. Lambda表达式介绍(转)

    刚开始学lambda,lambda与linq的联合使用. Lambda表达式实际上是一个匿名函数.它包含表达式和语句,常用于创建委托或表达式目录树类型.所有Lambda表达式都是用Lambda运算符- ...

  3. jQuery 初识 筛选器 属性选择器

    ---------------------------大事使我们惊讶,小事使我们沮丧,久而久之,我们对这二者都会习以为常. 一 jQuery是什么? [1]   jQuery由美国人John Resi ...

  4. PS调出清新淡雅外景女生背影照

    首先,依然是前期事项. 这套图是八月份下午三点多在草地上拍的(好像标题的秋日欺骗了大众XD),阳光很烈,不过也因为这样,能拍出比较清新的蓝天.用的是腾龙70-200 2.8VC拍摄,长焦在拍这种空旷大 ...

  5. static特别用法【静态导包】——Java包的静态导入

    面试我问你static关键字有哪些作用,如果你答出static修饰变量.修饰方法我会认为你合格,答出静态块,我会认为你不错,答出静态内部类我会认为你很好,答出静态导包我会对你很满意,因为能看出你非常热 ...

  6. springBoot项目启动类启动无法访问

    springBoot项目启动类启动无法访问. 网上也查了一些资料,我这里总结.下不来虚的,也不废话. 解决办法: 1.若是maven项目,则找到右边Maven Projects --->Plug ...

  7. nmon for Linux & Java

    nmon for Linux | Main / HomePagehttp://nmon.sourceforge.net/pmwiki.php Java Nmon Analyser download | ...

  8. js 正则进阶regexp

    一.匹配中文,英文字母和数字及_: const reg = /^[\u4e00-\u9fa5\w]+$/; const str1 = 'shangyy'; const str2 = '尚悦悦ww123 ...

  9. vue处理异步数据踩过的坑

    在开发时,由于数据是异步的导致页面在render 时data是空值 出现报错和警告. 我是这么处理的 把data先写出一个空的完整结构.暂时是这么处理 或者用三元表达式进行赋值监听.data ?myd ...

  10. Java 简单的登录验证码

    1 验证码的作用 验证码是为了区分人与机器,如果没有验证码机制,web网站或者应用会遇到很多问题,具体如下: ① 网站容易被暴力登录攻破密码,可以制作一个自动程序不断的尝试登录,密码很容易被破解,系统 ...