AC自动机,树上莫队,树状数组。。

  比赛的时候完全看不出来...赛后去膜了一波网上题解才明白= =

  离线,先把AC自动机建出来,把fail边反向建出fail树。

  发射言弹,就是将言弹结束节点的fail子树内点权+1;

  查询证言受的伤害,就是查询证言的每个前缀的结束节点的点权和。

  前缀的结束节点的点权和,也就是AC自动机上,根到证言结束位置路径上的点权和。

  每一个查询,就是查询在一段时间内,根到证言结束位置路径上的点权和。。。

  所以就树上莫队一波了。。前两维时间,第三维是AC自动机上的位置。。再来个树状数组维护一波...

  时间复杂度O(n^(3/5)logn)。。。。卡时过的。。。还要注意一下块的大小。。。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. #define ll long long
  7. using namespace std;
  8. const int maxn=<<;
  9. struct zs{int too,pre;}e[maxn];int tt,last[maxn];
  10. struct ask{int x,tim,timl,id;}b[maxn];
  11. int B[maxn];
  12. int ch[maxn][],fail[maxn],dl[maxn],cnt;
  13. int dfn[maxn],mp[maxn],TIME,L[maxn],R[maxn],TIM;
  14. int pos[maxn],pos1[maxn],tim1[maxn],a[maxn];
  15. int i,j,k,n,m;
  16. ll sum,an[maxn];
  17. bool u[maxn];
  18.  
  19. int ra;char rx;
  20. inline int read(){
  21. rx=getchar(),ra=;
  22. while(rx<''||rx>'')rx=getchar();
  23. while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
  24. }
  25.  
  26. void dfs(int x){
  27. L[x]=++TIM;
  28. for(int i=last[x];i;i=e[i].pre)
  29. dfs(e[i].too);
  30. R[x]=TIM;//printf(" x:%d l--r:%d %d\n",x,L[x],R[x]);
  31. }
  32. void dfs2(int x){
  33. dfn[x]=++TIME,mp[TIME]=x;//printf("x:%d dfn:%d\n",x,dfn[x]);
  34. for(int i=;i<;i++)if(ch[x][i])
  35. dfs2(ch[x][i]);
  36. mp[++TIME]=x;
  37. }
  38. inline void insert(int a,int b){e[++tt].too=b,e[tt].pre=last[a],last[a]=tt;/*printf("%d-->%d\n",a,b);*/}
  39.  
  40. int t[maxn],t1[maxn];
  41. inline void add1(int x){/*printf(" add1:%d\n",x);*/while(x<=cnt)t1[x]++,x+=x&-x;}
  42. inline void del1(int x){/*printf(" del1:%d\n",x);*/while(x<=cnt)t1[x]--,x+=x&-x;}
  43. inline int get1(int l,int r){
  44. int sm=;//printf(" get1:%d--%d",l,r);
  45. l--;while(l)sm-=t1[l],l-=l&-l;
  46. while(r)sm+=t1[r],r-=r&-r;/*printf(": %d\n",sm);*/return sm;
  47. }
  48.  
  49. inline int get(int x){
  50. // printf("get:%d",x);
  51. int sm=;while(x)sm+=t[x],x-=x&-x;//printf(" %d\n",sm);
  52. return sm;
  53. }
  54. inline void add(int l,int r){
  55. if(!l)return;//printf("add: %d--%d\n",l,r);
  56. sum+=get1(l,r);
  57. while(l<=cnt)t[l]++,l+=l&-l;
  58. r++;while(r<=cnt)t[r]--,r+=r&-r;
  59. }
  60. inline void del(int l,int r){
  61. if(!l)return;//printf("del: %d--%d\n",l,r);
  62. sum-=get1(l,r);
  63. while(l<=cnt)t[l]--,l+=l&-l;
  64. r++;while(r<=cnt)t[r]++,r+=r&-r;
  65. }
  66.  
  67. void getfail(){
  68. int l=,r=,i,p,now,j;dl[]=;
  69. while(l<r){
  70. now=dl[++l];
  71. for(i=;i<;i++)if(ch[now][i]){
  72. dl[++r]=j=ch[now][i];
  73. for(p=fail[now];p&&!ch[p][i];p=fail[p]);
  74. fail[j]=!now?:ch[p][i],insert(fail[j],j);
  75. }
  76. }
  77. }
  78.  
  79. bool cmp(ask a,ask b){
  80. return B[a.timl]==B[b.timl]?(B[a.tim]==B[b.tim]?a.x<b.x:B[a.tim]<B[b.tim]):B[a.timl]<B[b.timl];
  81. }
  82. int main(){
  83. m=read();char id[],c[];int x,tm=,numb=,n=,n1=;
  84. for(i=;i<=m;i++){
  85. scanf("%s",id);
  86. if(id[]=='I'){
  87. n++,scanf("%s",c),c[]-='a',x=read();
  88. if(!ch[pos[x]][c[]])ch[pos[x]][c[]]=++cnt;//printf(" .. %d %d\n",pos[x],c[0]);
  89. pos[n]=ch[pos[x]][c[]];//,tim[n]=tm;
  90. }
  91. if(id[]=='A'){
  92. n1++,scanf("%s",c),c[]-='a',x=read();
  93. if(!ch[pos1[x]][c[]])ch[pos1[x]][c[]]=++cnt;//,printf(" %d %d\n",pos1[x],c[0]);
  94. pos1[n1]=ch[pos1[x]][c[]],tim1[n1]=tm;
  95. }
  96. if(id[]=='S')
  97. tm++,a[tm]=pos[read()];
  98. if(id[]=='Q')
  99. b[++numb].x=read(),b[numb].tim=tm,b[numb].timl=tim1[b[numb].x]+,b[numb].id=numb;
  100. }
  101. cnt++;
  102. getfail();
  103. dfs(),dfs2();int kuai=(int)pow(tm,1.8/)+;
  104. for(i=;i<=tm+;i++)B[i]=(i+kuai-)/kuai;
  105. for(i=;i<=numb;i++)b[i].x=dfn[pos1[b[i].x]];
  106. sort(b+,b++numb,cmp);
  107.  
  108. int l=,r=,pos=;L[]=R[]=,u[mp[]]=;
  109. for(i=;i<=numb;i++){
  110. // printf("ask: %d--%d %d--%d x:%d sum:%lld\n",b[i].timl,b[i].tim,B[b[i].timl],B[b[i].tim],b[i].x,sum);
  111. while(l>b[i].timl)l--,add(L[a[l]],R[a[l]]);
  112. while(r<b[i].tim)r++,add(L[a[r]],R[a[r]]);
  113. while(l<b[i].timl)del(L[a[l]],R[a[l]]),l++;
  114. while(r>b[i].tim)del(L[a[r]],R[a[r]]),r--;//printf("sum: %lld\n",sum);
  115. while(pos>b[i].x){
  116. if(u[mp[pos]])sum-=get(L[mp[pos]]),del1(L[mp[pos]]);else sum+=get(L[mp[pos]]),add1(L[mp[pos]]);
  117. u[mp[pos]]^=,pos--;
  118. }
  119. while(pos<b[i].x){
  120. pos++;//printf("x: %d dfn:%d L:%d\n",mp[pos],pos,L[mp[pos]]);
  121. if(u[mp[pos]])sum-=get(L[mp[pos]]),del1(L[mp[pos]]);else sum+=get(L[mp[pos]]),add1(L[mp[pos]]);
  122. u[mp[pos]]^=;
  123. }
  124. an[b[i].id]=sum;
  125. }
  126. for(i=;i<=numb;i++)printf("%lld\n",an[i]);
  127. }

[51nod Round15 E ]Danganronpa的更多相关文章

  1. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  2. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  3. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  4. 51Nod 1278 相离的圆

    51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...

  5. 51nod算法马拉松15

    智力彻底没有了...看来再也拿不到奖金了QAQ... A B君的游戏 因为数据是9B1L,所以我们可以hash试一下数据... #include<cstdio> #include<c ...

  6. 【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501 dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐. 时间 ...

  7. 【51Nod 1622】【算法马拉松 19C】集合对

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1622 简单题..直接暴力快速幂 #include<cstdio&g ...

  8. 【51Nod 1616】【算法马拉松 19B】最小集合

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1616 这道题主要是查询一个数是不是原有集合的一个子集的所有数的gcd. ...

  9. 【51Nod 1674】【算法马拉松 19A】区间的价值 V2

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1674 对区间分治,统计\([l,r]\)中经过mid的区间的答案. 我的 ...

随机推荐

  1. BCryptPasswordEncoder加密及判断密码是否相同

    项目中用到了BCryptPasswordEncoder对密码进行二次加密,需要注意的是,加密后的字符串比较长,数据库的长度至少为60位. 通过BCryptPasswordEncoder的加密的相同字符 ...

  2. APP上传APP Store遇到的各种问题

    内容含敏感话题或对苹果不友好的信息(如苹果婊) 使用了友盟的统计SDK,获取了IDFA但是上传填写无广告 采用友盟IDFA的sdk,并用友盟的默认淘宝页面广告,被告知和产品内容不符(最近) App在i ...

  3. ASP.NET MVC下自定义错误页和展示错误页的几种方式

    在网站运行中,错误是不可避免的,错误页的产生也是不可缺少的. 这几天看了博友的很多文章,自己想总结下我从中学到的和实际中配置的. 首先,需要知道产生错误页的来源,一种是我们的.NET平台抛出的,一种是 ...

  4. jquery提供的插件无法删除cookie的解决办法

    之前使用jquery的cookie插件提供的 $.cookie("key",null)方法删除cookie,结果发现代码中的cookie一直无法删除,导致后面的种种问题. 经过各种 ...

  5. Paho -物联网 MQTT C Cient的实现和详解

    概述   在文章Paho - MQTT C Cient的实现中,我介绍了如何使用Paho开源项目创建MQTTClient_pulish客户端.但只是简单的介绍了使用方法,而且客户端的结果与之前介绍的并 ...

  6. 跟我一起学JQuery插件开发教程

    在逛codeproject网站的时候,突然看到一篇文章:How to write plugin in Jquery. 如果对E文好的同学 ,可以看上面的连接.现在我把上面网站的及结合自己的想法写这篇文 ...

  7. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  8. PCoA主坐标分析

    来源:http://blog.sina.com.cn/s/blog_670445240101nlss.html 1   背景介绍 这是一种排序方法.假设我们对N个样方有了衡量它们之间差异即距离的数据, ...

  9. Python函数返回不定数量的值

    Python的函数是可以return多个值的,但其本质上还是返回单个值,只是利用了tuple的自动打包,将多个值打包成单个tuple返回. 使用代码验证: def func_a(): return 1 ...

  10. css多重边框

    一.使用box-shadow实现多重边框 html <div class="multiple"></div> css .multiple{ backgrou ...