BZOJ4545: DQS的trie 广义后缀自动机_LCT_未调完

实在是调不下去了,以后找时间再继续调吧......

Code:

#include <queue> 
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector> 
#define setIO(s) freopen(s".in","r",stdin)//     ,freopen(s".out","w",stdout) 
#define maxn 800000 
#define N 2 
#define ll long long 
using namespace std; 
char str[maxn]; 
long long cur_ans; 
struct LCT{
    int ch[maxn][2],f[maxn],tag[maxn],sta[maxn],val[maxn]; 
    int get(int x){ return ch[f[x]][1]==x;}
    int isRoot(int x){  return !(ch[f[x]][1]==x||ch[f[x]][0]==x); }
    int lson(int x) { return ch[x][0];}
    int rson(int x){ return ch[x][1];} 
    void add(int x,int delta){
        if(!x) return;
        val[x]+=delta,tag[x]+=delta; 
    } 
    void pushdown(int x){
        if(tag[x]) {
            add(lson(x),tag[x]),add(rson(x),tag[x]); 
            tag[x] = 0; 
        }
    }
    void rotate(int x){
        int old=f[x],fold=f[old],which=get(x);
        if(!isRoot(old)) ch[fold][ch[fold][1]==old]=x; 
        ch[old][which]=ch[x][which^1],f[ch[old][which]]=old; 
        ch[x][which^1]=old,f[old]=x,f[x]=fold; 
    }
    void splay(int x){
        int v=0,u=x;
        sta[++v] = u; 
        while(!isRoot(u)) sta[++v]=f[u],u=f[u];
        while(v) pushdown(sta[v--]); 
        u=f[u];
        for(int fa;(fa=f[x])!=u;rotate(x)) 
            if(f[fa]!=u) rotate(get(fa)==get(x) ? fa : x); 
    }
    void Access(int x){ 
        for(int y=0;x;y=x,x=f[x]) 
            splay(x),ch[x][1]=y; 
    }
    void link(int a,int b){                   
        Access(a);
        splay(a);   
        add(a,val[b]) ,f[b]=a; 
    }
    void cut(int b){    
        Access(b),splay(b);
        add(lson(b),-val[b]),f[lson(b)]=ch[b][0]=0;  
    }
}tree; 
struct SAM{          
    int last,tot,dis[maxn],ch[maxn][30]; 
    int f[maxn]; 
    void init(){ last=tot=1; }
    int ins(int c){
        int p=last,np=++tot; 
        last=np,dis[np] = dis[p] + 1; 
        tree.val[np] = tree.tag[np] = 1;       
        while(p && !ch[p][c]) ch[p][c] = np,p=f[p]; 
        if(!p) f[np] = 1,tree.link(1,np);           
        else {
            int q=ch[p][c],nq;             
            if(dis[q] == dis[p] + 1) f[np] = q,tree.link(q,np);
            else {
                nq=++tot; 
                tree.val[nq] = 0;                        
                dis[nq] = dis[p] + 1;
                memcpy(ch[nq],ch[q],sizeof(ch[q])); 
                f[nq] = f[q];
                cur_ans+=dis[nq] - dis[f[nq]]; 
                cur_ans-=(dis[q] - dis[f[q]]); 
                tree.link(f[q],nq),tree.cut(q),tree.link(nq,q),tree.link(nq,np); 
                f[q] = f[np] = nq;             
                cur_ans+=(dis[q] - dis[f[q]]); 
                while(p && ch[p][c] == q) ch[p][c] = nq, p = f[p]; 
            }
        }
        cur_ans+=dis[np] - dis[f[np]]; 
        return np; 
    }
}sam; 
struct Node{
    int u,c; 
    Node(int u=0,int c=0):u(u),c(c){} 
}; 
queue <int> Q; 
vector <int> mark; 
vector <Node> G[maxn]; 
int idx[maxn]; 
void build_Tree(int n,int st){       
    for(int i=1;i<n;++i) {
        int u,v; 
        char c[2]; 
        scanf("%d%d",&u,&v);
        scanf("%s",c);  
        G[u].push_back(Node(v,c[0]-'0'));
        mark.push_back(u),mark.push_back(v);       
    }                
    Q.push(st);                   
    while(!Q.empty()) { 
        int u =Q.front(); Q.pop();                 
        int sz=G[u].size();  
        for(int i=0;i<sz;++i){
            int v=G[u][i].u; 
            int c=G[u][i].c; 
            sam.last=idx[u];                   
            idx[v]=sam.ins(c);     
            Q.push(v);
        }            
    } 
    int kk=mark.size();
    for(int i=0;i<kk;++i) 
        G[mark[i]].clear();        
}
int main(){
    setIO("input");            
    int lll,n,m;  
    scanf("%d",&lll);
    sam.init(),idx[1] = 1;  
    scanf("%d",&n);
    build_Tree(n,1);        
    scanf("%d",&m); 
    for(int i=1;i<=m;++i) {
        int opt_idx,a,b; 
        scanf("%d",&opt_idx); 
        if(opt_idx==1)  printf("%lld\n",cur_ans);  
        if(opt_idx==2) {
            scanf("%d%d",&a,&b);
            build_Tree(b,a);   
        }
        if(opt_idx==3) { 
            scanf("%s",str); 
            a=strlen(str); 
            b=idx[1]; 
            bool flag = 0; 
            for(int j=0;j<a;++j) { 
                b=sam.ch[b][str[j]-'0']; 
                if(!b)  flag = 1; 
            }
            if(flag) printf("0\n");  
            else {
                tree.Access(idx[b]); 
                tree.splay(idx[b]); 
                printf("%d\n",tree.val[idx[b]]); 
            }
        }
    }
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/10625484.html