zoukankan      html  css  js  c++  java
  • BZOJ 十连测 可持久化字符串

    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('
    '); }
    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;
    }
  • 相关阅读:
    Nginx 负载均衡
    wordpress 页面显示指定分类文章
    Linux 下 wordpress 无法安装插件
    在 Linux 上安装配置 BitTorrent Sync [转]
    nagios 配置 check_traffic 流量监控模块(Server 端)
    install nagios pnp4nagios on centos 6
    bat 脚本处理windows 文件
    Mac 下重新安装配置ibm Lotus 邮箱
    Domino 邮箱服务器接收不存在的邮箱账号的邮件
    Linux 下统计Apache每分钟的并发数
  • 原文地址:https://www.cnblogs.com/rrsb/p/8580477.html
Copyright © 2011-2022 走看看