洛谷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 ...
随机推荐
- eclipse maven 常见问题解决方案
一.eclipse集成与设置 传送门:http://www.cnblogs.com/tweet/p/7602044.html 二.创建maven webapp工程,报错 报错信息:Could not ...
- vue 饿了么项目笔记
vue 饿了么项目 1.图标字体引用 链接 2.scss 二三倍图切换 1像素边框 链接 3.better-scroll 4.布局 商品主页面 <div id="app"&g ...
- logstash grok内置规则
logstash grok 内置正则 https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns USERNAME [ ...
- [2019BUAA软工助教]Alpha阶段无人转出申请审核结果
[2019BUAA软工助教]Alpha阶段无人转出申请审核结果 一.队伍信息 队伍名 项目 人数 红太阳 社团 8(6+2) pureman 博客园 6 水哥牛逼 招募 6 葫芦娃 拖拽Pytorch ...
- 牛客练习赛 A题 筱玛的快乐
链接:https://ac.nowcoder.com/acm/contest/342/A来源:牛客网 筱玛的快乐 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语 ...
- 未能加载文件或程序集"Newtonsoft.Json, Version=4.5.0.0
这问题遇到好几次了,重新更改了引用都不好使,有的时候版本改成一致就好了,但是有的地方你不知道在哪里用了就不好排查,所性在config里面加个配置让程序运行的时候去处理得了~ 很实用,放在configu ...
- debian中完全删除mysql
参考自:http://www.jb51.net/article/50884.htm 之前实验室的人说找不到完全删除已安装的mysql-cluster的方法,我当时没在意,今天不得不删除他之前安装的my ...
- Notepad++远程连接Linux系统
首先在官网下载 https://notepad-plus-plus.org/news/notepad-7.6.4-released.html 在命令行数输入ifconfig 查看自己的Linux的ip ...
- jmeter压测
一般压测时间:10-15分钟 这些并发用户一直在请求. 稳定性测试:一周 2天 衡量性能好坏的指标: tps 服务端每秒钟能处理的请求数 rt响应时间 就是你从发出请求到服务器端返回所需的时间. ...
- Html5使用canvas作图
以下例子是项目中实际用到的.不足之处请大家指正,设计到画线,写文字,填充,文字旋转. <!DOCTYPE html> <html> <head lang="en ...