洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析:
从$\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] 蚯蚓排队 【哈希】的更多相关文章
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
- 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)
Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 【题解】洛谷P2827 [NOIP2016TG] 蚯蚓(优先队列)
题目来源:洛谷P2827 思路 阅读理解题 一开始以为是裸的优先队列而已 但是发现维护一个切开并且其他的要分别加上一个值很不方便 而且如果直接用优先队列会TLE3到4个点 自测85分 所以我们需要发现 ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- 【题解】洛谷P1966 [NOIP2013TG] 火柴排队(树状数组+逆序对)
次元传送门:洛谷P1966 思路 显然在两排中 每排第i小的分别对应就可取得最小值(对此不给予证明懒) 所以我们只在意两排的火柴是第几根 高度只需要用来进行排序(先把两个序列改成有序的方便离散化) 因 ...
- 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】
UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...
随机推荐
- Python股票分析系列——获得标普500的所有公司股票数据.p6
该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第6部分. 在之前的Python教程中,我们介绍了如何获取我们感兴趣的公司名单(在我们的案例中是 ...
- 解决win7 win10上网卡慢问题
在管理员身份运行CMD命令行,然后输入netsh interface tcp set global autotuninglevel=disable 即可.
- c++之sizeof的用法
在此温习一下c语言中sizeof的用法以及c++11.0的标准中,关于初始化的新方式,先上代码: # include "iostream" # include "stri ...
- mysql创建数据库命令
CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
- Java面试题详解一:面向对象三大特性
一,多态:1.面向对象四大基本特性:抽象,封装,继承,多态抽象,封装,继承是多态的基础.多态是抽象,封装,继承的表现.2.什么是多态不同类的对象对同一消息作出不同的响应叫做多态3.多态的作用简单来说: ...
- asp.net mvc Areas 母版页动态获取数据进行渲染
经常需要将一些通用的页面元素抽离出来制作成母版页,但是这里的元素一般都是些基本元素,即不需要 进行后台数据交换的基本数据,但是对于一些需要通过后台查询的数据,我们应该怎么传递给前台的母版页呢 这里描述 ...
- Errors running builder 'DeploymentBuilder' on project
Errors running builder 'DeploymentBuilder' on project 1.修改java源代码后点击保存,IDE 自动编译并热部署,提示如下错误: Errors o ...
- SQLServer2016 之后增加了索引列数的限制 从 16个列 增加到了 32个列
创建带有包含列的索引 https://docs.microsoft.com/zh-cn/sql/relational-databases/indexes/create-indexes-with-inc ...
- 头文件带和不带.h的区别
所有C++标准库的头文件都是没有.h结尾的.这么做是为了区分,C标准库的头文件和C++标准库的头文件.比如最具代表性的: #include <string.h> // C 标准库头文件,包 ...
- 《笔记》Apache2 mod_wsgi的配置
接手了一台古老的服务器的还使用的是mod_wsgi,所以需要配置一下.其实这里有点怀念,记得当年自己折腾第一个app的时候,还是个什么都不懂的菜鸡.当时用django搜方案的时候,还不知道有uwsgi ...