• bzoj2555


    开始时间:19:40

    完成时间:21:00

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555

    题目大意:(1):在当前字符串的后面插入一个字符串
        
            (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

    题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #define maxn 1200005
      7 #define maxl 3000005
      8 using namespace std;
      9 int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn];
     10 char st[maxl];
     11 char ss[20];
     12 struct data{
     13     int fa[maxn],son[maxn][2];
     14     int isroot(int x) {return (son[fa[x]][0]!=x && son[fa[x]][1]!=x);}
     15     int which(int x){return son[fa[x]][1]==x;}
     16     void change(int x,int k){ ri[x]+=k; lazy[x]+=k;}
     17     void pushdown(int x)
     18     {
     19         if (!lazy[x]) return;
     20         if (son[x][1]) change(son[x][1],lazy[x]);
     21         if (son[x][0]) change(son[x][0],lazy[x]);
     22         lazy[x]=0;
     23     }
     24     void relax(int x){if (!isroot(x)) relax(fa[x]); pushdown(x);}
     25     void turn(int x){
     26         int y=fa[x],wx=which(x),wy=which(y);
     27         if (!isroot(y)) son[fa[y]][wy]=x; fa[x]=fa[y];
     28         son[y][wx]=son[x][1-wx]; fa[son[x][1-wx]]=y; 
     29         son[x][1-wx]=y; fa[y]=x;
     30     }
     31     void splay(int x)
     32     {
     33         relax(x);
     34         while (!isroot(x))
     35         {
     36             if (isroot(fa[x])) turn(x);
     37             else if (which(x)==which(fa[x])) turn(fa[x]),turn(x);
     38             else turn(x),turn(x);
     39         }
     40     }
     41     void access(int x)
     42     {
     43         for (int p=0; x; x=fa[x]){ splay(x); son[x][1]=p; p=x;}
     44     }
     45     void link(int x,int y){
     46         fa[x]=y; access(y); splay(y); change(y,ri[x]);
     47     }
     48     void cut(int x)
     49     {
     50         access(x); splay(x); change(son[x][0],-ri[x]); fa[son[x][0]]=0; son[x][0]=0;
     51     }
     52 }lct;
     53 struct date{
     54     int fa[maxn],son[maxn][26],val[maxn];
     55     void prepare(){root=tot=last=1;}
     56     int newnode(int x){val[++tot]=x; return tot;}
     57     void extend(int x)
     58     {
     59         int p=last,np=newnode(val[p]+1);ri[np]=1;last=np;
     60         for (; p&&!son[p][x]; p=fa[p]) son[p][x]=np; 
     61         if (!p) fa[np]=root,lct.link(np,root);
     62         else
     63         {
     64             int q=son[p][x];
     65             if (val[q]==val[p]+1){fa[np]=q; lct.link(np,q);}
     66             else
     67             {
     68                 int nq=newnode(val[p]+1);ri[nq]=0;
     69                 memcpy(son[nq],son[q],sizeof(son[q]));
     70                 fa[nq]=fa[q]; lct.cut(q),lct.link(nq,fa[nq]);
     71                 fa[q]=fa[np]=nq; lct.link(q,nq),lct.link(np,nq);
     72                 for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq; 
     73             }
     74         }
     75     }
     76     void build()
     77     {for (int i=1; i<=m; i++) extend(st[i]-'A');}
     78     void query(){
     79         int x,y;
     80         bool can=1;
     81         x=root;
     82         for (int i=1;i<=m;i++){
     83             y=st[i]-'A';
     84             if (!son[x][y]){
     85                 can=0;
     86                 break;
     87             }else{
     88                 x=son[x][y];
     89             }
     90         }
     91         if (can==0||x==root) puts("0");
     92         else{
     93             lct.splay(x);
     94             printf("%d
    ",ri[x]),mark^=ri[x];
     95         }
     96     }
     97 }SAM;
     98 void unzip(){
     99     int temp=mark;
    100     for (int i=1;i<=m;i++){
    101         temp=(temp*131+i-1)%m+1;
    102         char t=st[i]; st[i]=st[temp],st[temp]=t,temp--;
    103     }
    104 }
    105 int main()
    106 {
    107     scanf("%d
    ",&q);mark=0;
    108     scanf("%s",st+1); m=strlen(st+1);
    109     SAM.prepare();
    110     SAM.build();
    111     for (int i=1; i<=q; i++)
    112     {
    113         scanf("%s",ss);scanf("%s",st+1); m=strlen(st+1);unzip(); 
    114         if (ss[0]=='A') SAM.build();
    115         else SAM.query();
    116     }
    117 }
    View Code
  • 相关阅读:
    JSP中 == 和equals的区别
    使用Cookie保存用户名密码,再次登陆时将Cookie用户名密码取出来并直接放置到用户名密码文本框中
    学习Java Web开发中遇到的问题,及其解决方法
    部署、测试、服务工作的经验记录
    Python基础--dict字典操作
    Python基础--dict字典
    Python基础--预留空 5
    Python基础--预留空 4
    Python基础--tuple 元组
    Python基础--预留3
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5550830.html
Copyright © 2020-2023  润新知