码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 十连测 可持久化字符串

时间:2018-03-16 13:34:52      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:i++   har   bzoj   zoj   struct   body   lin   ati   gpo   

SOL:

   我们发现答案就是 跑一边KMP 那么答案就是i-net[i],

   我们考虑在trie上跑KMP,我们发现KMP的复杂度是依赖摊还分析的线性复杂度。如果朴素的KMP做法时间复杂度是不对的。

比如这样一个trie:  a

                                |

                                a

                                |
                                a

                            /        \

                         b             b

   复杂度就退化了。那么我们可以考虑对每一个节点开一个数组:

    f[i] 记下当前的节点后查入i元素后的kmp值。

     我们可以发现当前节点的f和其net的f是差不多的,只要将net的f  copy一遍 ,再讲net的后继插进来就好了。

     我们可以用主席树来维护f

     O(nlogn)

#include<bits/stdc++.h>
using namespace std;
#define sight(c) (‘0‘<=c&&c<=‘9‘)
#define N 300007
inline void read(int &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
void write(int x){if (x<10) {putchar(0+x); return;} write(x/10); putchar(0+x%10);}
inline void writeln(int x){ if (x<0) putchar(-),x*=-1; write(x); putchar(\n); }
inline void writel(int x){ if (x<0) putchar(-),x*=-1; write(x); putchar( ); }
struct Node{
    int l,r,x;
}te[N<<5];
int tot,anw,n,m,op,fr,at,lastans,l,len[N],rot[N],fp[N],opt,Le;
int f[N][21];
#define Mid (l+r>>1)
void ins(int X,int & now,int l,int r,int id,int x) {
    now=++tot; te[now]=te[X];
    if (id==Mid) {te[now].x=x;return;}
    if (id<Mid) ins(te[X].l,te[now].l,l,Mid-1,id,x);
    else ins(te[X].r,te[now].r,Mid+1,r,id,x);
}
void que(int X,int l,int r,int x){
    if (Mid==x) {anw=te[X].x; return;}
    if (x<Mid) que(te[X].l,l,Mid-1,x);
    else que(te[X].r,Mid+1,r,x);
}
signed main () {
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    read(n); read(m); read(op);
    for (int i=1;i<=n;i++) {
        read(fr); read(at); 
        if (op) fr^=lastans,at^=lastans;
        fp[i]=at; f[i][0]=fr; l=len[i]=len[fr]+1;
        for (int j=1;j<=20;j++) f[i][j]=f[f[i][j-1]][j-1];
        que(rot[fr],1,m,at); 
        writeln(lastans=(l-len[anw]));
        opt=i; Le=len[anw]+1;
        for (int j=20;~j;j--) if (len[f[opt][j]]>=Le) opt=f[opt][j];
        ins(rot[anw],rot[i]=++tot,1,m,fp[opt],opt);
    } 
    return 0;
}

 

BZOJ 十连测 可持久化字符串

标签:i++   har   bzoj   zoj   struct   body   lin   ati   gpo   

原文地址:https://www.cnblogs.com/rrsb/p/8580477.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!