题目分析:

从$\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|)$

代码:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 using namespace std;
  6
  7 const int maxsz = 450;
  8 const int maxn = 505000;
  9 const int mod = 998244353;
 10 const int hmod1 = 19260817;
 11 const int hmod2 = 19491001;
 12
 13 int n,m,maxx;
 14 int a[maxn],pts[maxn];
 15 int ans[maxn],Num,nouse[94],nuse[91];
 16 int hsh[hmod1+5],Nxt[maxn*25],real[maxn*25],val[maxn*25],hnum;
 17
 18 struct query{ int cas;string str; int l,r; }Q[maxn];
 19
 20 int global = 0;
 21
 22 struct linktable{int pre[maxn>>1],nxt[maxn>>1];}T;
 23
 24 void in(int &x){
 25     char ch = getchar();
 26     while(ch > '9' || ch < '0') ch = getchar();
 27     while(ch <= '9' && ch >= '0') x = x*10+ch-'0',ch = getchar();
 28 }
 29
 30 void readstring(string &str){
 31     char ch = getchar();
 32     while(ch > '9' || ch < '0') ch =getchar();
 33     while(ch <= '9' && ch >= '0') str.push_back(ch),ch=getchar();
 34 }
 35
 36 void read(){
 37     in(n),in(m);
 38     for(int i=1;i<=n;i++) {in(a[i]);}
 39     for(int i=1;i<=m;i++){
 40     in(Q[i].cas);
 41     if(Q[i].cas == 1) in(Q[i].l),in(Q[i].r);
 42     else if(Q[i].cas == 2) in(Q[i].l);
 43     else {readstring(Q[i].str),in(Q[i].l);Q[i].r = ++Num;maxx = max(maxx,Q[i].l);}
 44     }
 45 }
 46
 47 int imnum[60],numnum;
 48
 49 void Add_hash(int a1,int a2,int dr){
 50     int p1 = hsh[a1];
 51     while(true) {
 52     if(real[p1] == a2) {val[p1]+=dr;return;}
 53     if(Nxt[p1]) p1 = Nxt[p1];
 54     else break;
 55     }
 56     hnum++; if(p1) Nxt[p1] = hnum;
 57     p1 = hnum; val[p1] = 1; real[p1] = a2;
 58     if(!hsh[a1]) hsh[a1] = p1;
 59 }
 60
 61 void buildnew(int lft,int rgt,int dr){
 62     numnum = 0;int now = lft;
 63     while(true){
 64     if(numnum == maxx-1) break;
 65     imnum[++numnum] = a[now];
 66     if(T.pre[now]) now = T.pre[now];
 67     else break;
 68     }
 69     now = rgt;long long um = 0,vm = 0;
 70     for(int i=1;i<=numnum;i++){
 71     um = (1ll*nouse[i-1]*imnum[i]+um)%hmod1;
 72     vm = (1ll*nuse[i-1]*imnum[i]+vm)%hmod2;
 73     long long r1 = um,r2 = vm;
 74     for(int j=i+1,jj=rgt;j<=maxx;j++){
 75         r1 = (r1*10+a[jj])%hmod1; r2 = (r2*10+a[jj])%hmod2;
 76         Add_hash(r1,r2,dr); if(!T.nxt[jj])break; jj = T.nxt[jj];
 77         global++;
 78     }
 79     }
 80 }
 81
 82 void link(int lft,int rgt){
 83     buildnew(lft,rgt,1);
 84     T.nxt[lft] = rgt; T.pre[rgt] = lft;
 85 }
 86
 87 void cut(int place){
 88     buildnew(place,T.nxt[place],-1);
 89     T.pre[T.nxt[place]] = 0; T.nxt[place] = 0;
 90 }
 91
 92 int COUNT(int alpha,int beta){
 93     int fw = 0;
 94     for(int i=hsh[alpha];i;i=Nxt[i]){
 95     if(real[i] != beta) continue;
 96     fw += val[i];
 97     }
 98     return fw;
 99 }
100
101 void work(){
102     for(int i=1;i<=n;i++) nouse[a[i]]++;
103     for(int i=1;i<=m;i++){
104     if(Q[i].cas != 3 || Q[i].l != 1) continue;
105     int fw = 1; for(int j=0;j<Q[i].str.length();j++){fw = (1ll*fw*nouse[Q[i].str[j]-'0'])%mod;}
106     ans[Q[i].r] = fw;
107     }
108     memset(nouse,0,sizeof(nouse)); nouse[0] = 1;nuse[0] = 1;
109     for(int i=1;i<=55;i++) nouse[i] = (nouse[i-1]*10ll)%hmod1,nuse[i] = (nuse[i-1]*10ll)%hmod2;
110
111     for(int i=1;i<=m;i++){
112     if(Q[i].cas == 1) link(Q[i].l,Q[i].r);
113     else if(Q[i].cas == 2) cut(Q[i].l);
114     else{
115         if(Q[i].l == 1) continue;
116         int fw = 1;long long hres1=0,hres2 = 0;
117         for(int j=0;j<Q[i].l;j++){
118         hres1 = hres1*10+Q[i].str[j]-'0';
119         hres2 = hres2*10+Q[i].str[j]-'0';
120         hres1 %= hmod1; hres2 %= hmod2;
121         }
122         fw = (1ll*fw*COUNT(hres1,hres2))%mod;
123         for(int j=Q[i].l;j<Q[i].str.length();j++){
124         hres1 -= ((Q[i].str[j-Q[i].l]-'0')*nouse[Q[i].l-1])%hmod1;
125         hres1 += hmod1; hres1 %= hmod1;
126         hres2 -= ((Q[i].str[j-Q[i].l]-'0')*nuse[Q[i].l-1])%hmod2;
127         hres2 += hmod2; hres2 %= hmod2;
128         hres1 = (hres1*10+Q[i].str[j]-'0');hres1 %= hmod1;
129         hres2 = (hres2*10+Q[i].str[j]-'0');hres2 %= hmod2;
130         fw = (1ll*fw*COUNT(hres1,hres2))%mod;
131         }
132         ans[Q[i].r] = fw;
133     }
134     }
135     for(int i=1;i<=Num;i++) printf("%d\n",ans[i]);
136 }
137
138 int main(){
139     read();
140     work();
141     return 0;
142 }

转载于:https://www.cnblogs.com/Menhera/p/9211515.html

洛谷3823 [NOI2017] 蚯蚓排队 【哈希】相关推荐

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

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

  2. 洛谷P2462 [SDOI2007]游戏(哈希+最长路)

    题面 传送门 题解 我们把字符的出现次数哈希起来,然后把每个点向能在它之后的点连边.那么这显然是一个\(DAG\),直接求最长路就行了 //minamoto #include<bits/stdc ...

  3. 洛谷4895 独钓寒江雪 (树哈希+dp+组合)

    qwq 首先,如果是没有要求本质不同的话,那么还是比较简单的一个树形dp 我们令dp[i][0/1]dp[i][0/1]dp[i][0/1]表示是否iii的子树,是否选iii这个点的方案数. 一个比较 ...

  4. 【洛谷P1966】火柴排队

    两列排序后将编号一一对应 归并排序求逆序对 (每一次交换就去掉一个逆序对) 1 #include<cstdio> 2 #include<cstring> 3 #include& ...

  5. 洛谷P3879 [TJOI2010] 阅读理解 哈希Hash解法

    题目描述: 英语老师留了 N 篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过. 输入格式 第一行为整数 N ,表示短文篇数, ...

  6. 信息学奥赛一本通 1319:【例6.1】排队接水 | 洛谷 P1223 排队接水

    [题目链接] ybt 1319:[例6.1]排队接水 洛谷 P1223 排队接水 [题目考点] 1. 贪心 2. 贪心选择性质的证明 要想证明贪心选择可以得到最优解,只需要证明最优解包含每一次的贪心选 ...

  7. NOIP2013 火柴排队 [洛谷P1966]

    NOIP2013 火柴排队 [洛谷P1966] 题目描述 涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之 ...

  8. 洛谷 p1757 通天之分组背包(哈希,分组背包)2021-08-12

    题目背景 直达通天路·小 A 历险记第二篇 题目描述 自 01 背包问世之后,小 A 对此深感兴趣.一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组,每组中的物品相互 ...

  9. 洛谷or牛客数据结构+算法

    栈思想:先进后出 tips:栈里能放下标就放下标 (牛客)小c的计事本(直接用stack可以简化代码,且不会被自己绕晕,当时没意识到) (牛客)吐泡泡(没意识到用栈),(牛客)好串 1.后缀表达式(栈 ...

  10. 洛谷 P1843 奶牛晒衣服

    题目背景 熊大妈决定给每个牛宝宝都穿上可爱的婴儿装 . 于是 , 为牛宝宝洗晒衣服就成了很不爽的事情. 题目描述 熊大妈请你帮助完成这个重任 . 洗完衣服后 , 你就要弄干衣服 . 衣服在自然条件下用 ...

最新文章

  1. 计算机的英语怎么写的英语怎么写,计算机英语怎么写
  2. 十八岁华裔天才携手「量子计算先驱」再次颠覆量子计算
  3. corosync+pacemaker高可用集群
  4. 《FPGA全程进阶---实战演练》第一章之如何学习FPGA
  5. 【Java】Java 语言的初步认识及工作应用范围
  6. CV:利用cv2自带两步法haarcascade_frontalcatface.xml实现对猫脸检测
  7. linux中启动 java -jar 后台运行程序
  8. 后台传值给前台p标签
  9. android 自动打包工具,AutopackingAndroid
  10. vue基础之路由(概念,基本使用,路由规则中定义参数,路由的嵌套,使用路由进行经典布局)
  11. qq2008珊瑚虫版SL
  12. xlsx 解析excel 后渲染到表格里(前端实现 解析excel渲染到表格)
  13. 【超图+CESIUM】【基础API使用示例】18、超图|CESIUM - 标绘点位:Cesium.DrawHandler绘制点位Cesium.DrawMode.Point
  14. EBSD Channel5软件
  15. 国内可以使用的英文搜索引擎
  16. 3D编辑器-Web在线编辑基于WebGL/Threejs技术
  17. 10款电子邮箱测评:新浪邮箱、TOM邮箱、qq邮箱、163邮箱等产品差异明显,这款邮箱安全稳定性最高!
  18. 201621123068 Week02-Java基本语法与类库
  19. gmap 支持python吗_Python:地图上的标记标签使用gmap.marker_层使用hover_-tex选项不工作...
  20. pick_types()函数及参数 meg eeg stim eog ecg

热门文章

  1. 5814:无根树(技巧:树的直径BFS)
  2. android手机双开微信方法,安卓黑科技:一机同时双开多个QQ/微信
  3. HTTP 状态码502 深度解析
  4. ARM架构下常用GNU汇编程序伪指令介绍(Assembler Directive)
  5. 华为手机相册怎么镜像翻转_安卓手机相册为什么总会莫名出现照片,应该怎么彻底删除?...
  6. 计算机用手机的网络,台式电脑如何使用手机网络上网
  7. 图形化开发(五)041-Three.js之Camera相机——target焦点和lookAt()方法、OrthographicCamera正交相机、PerspectiveCamera透视相机、相机插件
  8. 苹果系统更新不了怎么办_iphone/ipad更新系统失败后怎么办?
  9. 一、Netflix Eureka
  10. 创建对象和实现原型继承的几种方式