• loj6070【山东集训第一轮Day4】基因


    • 题解:

      • 分块对每个块的起点$st[i]$到$n$做一次回文自动机;
      • 由于子串的回文自动机是原串的子图,所以并不需要重新构图,在原来的图上做即可;
      • 做的时候记录某个终点的本质不同的回文串和$sum[i][r]$
      • 对于询问$[l,r]$,直接统计$l$后的整块,考虑统计$l$所在的散块$[l,st[i]]$
      • 根据回文串的对称性,可以预处理出在$st[i]$匹配的最长回文后缀节点,所以从st[i]到l暴力即可;
      • 注意判断是否重复和是否超出边界;
      • 暂时还不会两个log的做法;
      •  1 #include<bits/stdc++.h>
         2 #define rg register
         3 using namespace std;
         4 const int M=320,N=200010;
         5 int T,n,m,typ,sz,ch[N][26],Fl[N][26],fl[N],end[M][N],pos[M][N];
         6 int sum[M][N],u,tot,bl[N],st[N],ed[N],lst,vis[N],len[N],s[N];
         7 inline char gc(){
         8     static char*p1,*p2,buf[1000000];
         9     if(p1==p2)p2=(p1=buf)+fread(buf,1,1000000,stdin);
        10     return(p1==p2)?EOF:*p1++;
        11 }
        12 inline int rd(){
        13     int x=0;char c=gc();
        14     while(c<'0'||c>'9')c=gc();
        15     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
        16     return x;
        17 }
        18 void extend1(int l,int i){
        19     int x=lst;
        20     if(i-len[x]-1<l||s[i-len[x]-1]!=s[i])x=Fl[x][s[i]];
        21     if(!ch[x][s[i]]){
        22         len[++sz]=len[x]+2;
        23         int y=fl[x];
        24         if(s[i-len[y]-1]!=s[i])y=Fl[y][s[i]];y=ch[y][s[i]];
        25         memcpy(Fl[sz],Fl[y],sizeof(Fl[y]));
        26         Fl[sz][s[i-len[y]]]=fl[sz]=y;
        27         ch[x][s[i]]=sz;
        28     }
        29     lst=x=ch[x][s[i]];
        30 }
        31 void extend2(int i,int r){
        32     int x=lst;
        33     if(i+len[x]+1>r||s[i+len[x]+1]!=s[i])x=Fl[x][s[i]];
        34     if(!ch[x][s[i]]){
        35         len[++sz]=len[x]+2;
        36         int y=fl[x];
        37         if(s[i+len[y]+1]!=s[i])y=Fl[y][s[i]];y=ch[y][s[i]];
        38         memcpy(Fl[sz],Fl[y],sizeof(Fl[y]));
        39         Fl[sz][s[i+len[y]]]=fl[sz]=y;
        40         ch[x][s[i]]=sz;
        41     }
        42     lst=x=ch[x][s[i]];
        43 }
        44 int main(){
        45     #ifndef ONLINE_JUDGE
        46     freopen("loj6070.in","r",stdin);
        47     freopen("loj6070.out","w",stdout);
        48     #endif
        49     typ=rd();n=rd();m=rd();
        50     u = sqrt(n);
        51     char c=gc();while(!isalpha(c))c=gc();
        52     for(int i=1;i<=n;++i,c=gc()){
        53         bl[i]=(i-1)/u+1;ed[bl[i]]=i;
        54         if(!st[bl[i]])st[bl[i]]=i;
        55         s[i]=c-'a';
        56     }tot=bl[n];
        57     sz=1;
        58     fl[0]=1;fl[1]=0;
        59     len[0]=0;len[1]=-1;
        60     for(rg int i=0;i<26;++i)Fl[0][i]=1; 
        61     memset(end,0x3f,sizeof(end));
        62     for(rg int i=1;i<=tot;++i){
        63         lst=0;T++;
        64         for(rg int j=st[i];j<=n;++j){
        65             extend1(st[i],j);
        66             sum[i][j]=sum[i][j-1];
        67             if(vis[lst]<T){
        68                 vis[lst]=T;
        69                 sum[i][j]++;
        70                 end[i][lst]=j;
        71             }
        72             if(len[lst]==j-st[i]+1)pos[i][j]=lst;
        73             else pos[i][j]=pos[i][j-1];
        74         }
        75     }
        76     int ans=0;
        77     for(rg int i=1,l,r;i<=m;++i){
        78         T++; 
        79         l=rd();r=rd();
        80         if(typ)l^=ans,r^=ans;
        81         if(bl[l]==bl[r]){
        82             lst=0;ans=0;
        83             for(rg int j=l;j<=r;++j){
        84                 extend1(l,j);
        85                 if(vis[lst]<T)vis[lst]=T,ans++;
        86             }
        87         }else{
        88             ans=sum[bl[l]+1][r];
        89             lst=pos[bl[l]+1][r];
        90             for(rg int j=ed[bl[l]];j>=l;--j){
        91                 extend2(j,r);
        92                 if(vis[lst]<T&&end[bl[l]+1][lst]>r)vis[lst]=T,ans++;
        93             }
        94         }
        95         printf("%d
        ",ans);
        96     }
        97     return 0;
        98 }
        loj6070
  • 相关阅读:
    P3952 [NOIP2017 提高组] 时间复杂度
    1905. 统计子岛屿
    1102 Invert a Binary Tree (25 分)
    P1077 [NOIP2012 普及组] 摆花
    P3915 树的分解
    P1045 [NOIP2003 普及组] 麦森数
    P4961 小埋与扫雷
    P1123 取数游戏
    P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
    CF1059B Forgery
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10311828.html
Copyright © 2020-2023  润新知