zoukankan      html  css  js  c++  java
  • [51nod Round15 E ]Danganronpa

      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=100233<<1;
      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][26],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=0;
     22     while(rx<'0'||rx>'9')rx=getchar();
     23     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,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
    ",x,L[x],R[x]);
     31 }
     32 void dfs2(int x){
     33     dfn[x]=++TIME,mp[TIME]=x;//printf("x:%d   dfn:%d
    ",x,dfn[x]);
     34     for(int i=0;i<26;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
    ",a,b);*/}
     39 
     40 int t[maxn],t1[maxn];
     41 inline void add1(int x){/*printf("  add1:%d
    ",x);*/while(x<=cnt)t1[x]++,x+=x&-x;}
     42 inline void del1(int x){/*printf("  del1:%d
    ",x);*/while(x<=cnt)t1[x]--,x+=x&-x;}
     43 inline int get1(int l,int r){
     44     int sm=0;//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
    ",sm);*/return sm;
     47 }
     48 
     49 inline int get(int x){
     50 //    printf("get:%d",x);
     51     int sm=0;while(x)sm+=t[x],x-=x&-x;//printf("  %d
    ",sm);
     52     return sm;
     53 }
     54 inline void add(int l,int r){
     55     if(!l)return;//printf("add:   %d--%d
    ",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
    ",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 
     68 void getfail(){
     69     int l=0,r=1,i,p,now,j;dl[1]=0;
     70     while(l<r){
     71         now=dl[++l];
     72         for(i=0;i<26;i++)if(ch[now][i]){
     73             dl[++r]=j=ch[now][i];
     74             for(p=fail[now];p&&!ch[p][i];p=fail[p]);
     75             fail[j]=!now?0:ch[p][i],insert(fail[j],j);
     76         }
     77     }
     78 }
     79 
     80 bool cmp(ask a,ask b){
     81     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];
     82 }
     83 int main(){
     84     m=read();char id[13],c[2];int x,tm=0,numb=0,n=0,n1=0;
     85     for(i=1;i<=m;i++){
     86         scanf("%s",id);
     87         if(id[0]=='I'){
     88             n++,scanf("%s",c),c[0]-='a',x=read();
     89             if(!ch[pos[x]][c[0]])ch[pos[x]][c[0]]=++cnt;//printf(" ..     %d %d
    ",pos[x],c[0]);
     90             pos[n]=ch[pos[x]][c[0]];//,tim[n]=tm;
     91         }
     92         if(id[0]=='A'){
     93             n1++,scanf("%s",c),c[0]-='a',x=read();
     94             if(!ch[pos1[x]][c[0]])ch[pos1[x]][c[0]]=++cnt;//,printf("      %d %d
    ",pos1[x],c[0]);
     95             pos1[n1]=ch[pos1[x]][c[0]],tim1[n1]=tm;
     96         }
     97         if(id[0]=='S')
     98             tm++,a[tm]=pos[read()];
     99         if(id[0]=='Q')
    100             b[++numb].x=read(),b[numb].tim=tm,b[numb].timl=tim1[b[numb].x]+1,b[numb].id=numb;
    101     }
    102     cnt++;
    103     getfail();
    104     dfs(0),dfs2(0);int kuai=(int)pow(tm,1.8/3)+3;
    105     for(i=0;i<=tm+1;i++)B[i]=(i+kuai-1)/kuai;
    106     for(i=1;i<=numb;i++)b[i].x=dfn[pos1[b[i].x]];
    107     sort(b+1,b+1+numb,cmp);
    108     
    109     int l=1,r=0,pos=1;L[0]=R[0]=0,u[mp[1]]=1;
    110     for(i=1;i<=numb;i++){
    111 //        printf("ask:  %d--%d  %d--%d  x:%d   sum:%lld
    ",b[i].timl,b[i].tim,B[b[i].timl],B[b[i].tim],b[i].x,sum);
    112         while(l>b[i].timl)l--,add(L[a[l]],R[a[l]]);
    113         while(r<b[i].tim)r++,add(L[a[r]],R[a[r]]);
    114         while(l<b[i].timl)del(L[a[l]],R[a[l]]),l++;
    115         while(r>b[i].tim)del(L[a[r]],R[a[r]]),r--;//printf("sum:  %lld
    ",sum);
    116         while(pos>b[i].x){
    117             if(u[mp[pos]])sum-=get(L[mp[pos]]),del1(L[mp[pos]]);else sum+=get(L[mp[pos]]),add1(L[mp[pos]]);
    118             u[mp[pos]]^=1,pos--;
    119         }
    120         while(pos<b[i].x){
    121             pos++;//printf("x: %d   dfn:%d  L:%d
    ",mp[pos],pos,L[mp[pos]]);
    122             if(u[mp[pos]])sum-=get(L[mp[pos]]),del1(L[mp[pos]]);else sum+=get(L[mp[pos]]),add1(L[mp[pos]]);
    123             u[mp[pos]]^=1;
    124         }
    125         an[b[i].id]=sum;
    126     }
    127     for(i=1;i<=numb;i++)printf("%lld
    ",an[i]);
    128 }
    View Code
  • 相关阅读:
    class-dump + DumpFrameworks.pl
    使用 U盘 重装 Mac OSX
    本地化应用程序
    UINavigationBar 总结
    Xcode 杂七杂八
    App 打包并跳过 AppStore 的发布下载
    Summary of Mac Versions
    QT5安装(null)
    如何实现LAN或WAN远程开机?
    DELL 8700重装系统
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5625729.html
Copyright © 2011-2022 走看看