• BZOJ2534: Uva10829L-gap字符串


    http://www.lydsy.com/JudgeOnline/problem.php?id=2534

      给定字符串S,求形式为ABA的子串个数,其中B的长度为L。

      考虑A的两个起始位置x,y(x<y),应该满足如下两个条件:

        1.y>x+L

        2.LCP(x,y)≥y-x-L

      我们按height从大到小枚举,这样LCP就是变成了当前的height,将两个集合统计答案并合并。统计答案时枚举size较小的集合内的点作为x或y即可。可以用平衡树或者主席树来维护。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=50015;
    typedef long long int64;
    typedef pair<int,int> PII;
    int n,l,cnt,q[maxn];
    int64 ans;char s[maxn];
    struct Tsplay{
        int tot;
        static const int maxnode=1000015;
        struct Tnode{
            Tnode *f,*c[2];int n,siz,val;
            void update(){siz=c[0]->siz+c[1]->siz+1;}
            void link(Tnode *newf,int newn){n=newn;f=newf;if (n!=2) f->c[n]=this;}
        }T[maxnode],*root[maxn],*null;
        void clear(){
            tot=0;null=T;null->c[0]=null->c[1]=null;null->siz=0;
            for (int i=1;i<=n;++i) root[i]=null;
        }
        Tnode *newnode(int v){
            Tnode *cur=T+(++tot);
            cur->f=cur->c[0]=cur->c[1]=null;
            cur->n=2;cur->val=v;cur->siz=1;
            return cur;
        }
        void rotate(Tnode *x){
            Tnode *y=x->f,*z=y->f;int nx=x->n,ny=y->n;
            x->link(z,ny);x->c[!nx]->link(y,nx);y->link(x,!nx);
            y->update();
        }
        void splay(int p,Tnode *x){
            while (x->n!=2){
                x->n==x->f->n?rotate(x->f):rotate(x);
                if (x->n!=2) rotate(x);
            }
            root[p]=x;x->update();
        }
        void insert(int p,int val){
            Tnode *x=root[p];
            if (x==null){root[p]=newnode(val);return;}
            while (1){
                if (val<x->val){
                    if (x->c[0]==null){x->c[0]=newnode(val);x->c[0]->link(x,0);splay(p,x->c[0]);return;}
                    else x=x->c[0];
                }
                else{
                    if (x->c[1]==null){x->c[1]=newnode(val);x->c[1]->link(x,1);splay(p,x->c[1]);return;}
                    else x=x->c[1];
                }
            }
        }
        int greater(int p,int v){
            Tnode *res=null,*x=root[p];
            while (x!=null){
                if (x->val>v){res=x;x=x->c[0];}
                else x=x->c[1];
            }
            if (res==null) return 0;
            else{splay(p,res);return res->c[1]->siz+1;}
        }
        int less(int p,int v){
            Tnode *res=null,*x=root[p];
            while (x!=null){
                if (x->val<v){res=x;x=x->c[1];}
                else x=x->c[0];
            }
            if (res==null) return 0;
            else{splay(p,res);return res->c[0]->siz+1;}
        }
        void travel(Tnode *x){
            if (x!=null) q[++cnt]=x->val;else return;
            travel(x->c[0]);travel(x->c[1]);
        }
        int size(int p){return root[p]->siz;}
        void travel(int x){cnt=0;travel(root[x]);}
        void merge(int t1,int t2){
            travel(t2);
            for (int i=1;i<=cnt;++i) insert(t1,q[i]);
        }
    }splay;
    struct Tsuffix_array{
        int sum[maxn],sa[maxn],rank[maxn],tsa[maxn],trank[maxn];
        bool cmp(int i,int j,int l){
            if (i+l>n||j+l>n) return 0;
            return rank[i]==rank[j]&&rank[i+l]==rank[j+l];
        }
        void suffix_sort(){
            int m=255,p,i,j;
            for (i=0;i<=m;++i) sum[i]=0;
            for (i=1;i<=n;++i) ++sum[rank[i]=s[i]];
            for (i=1;i<=m;++i) sum[i]+=sum[i-1];
            for (i=n;i>=1;--i) sa[sum[rank[i]]--]=i;
            for (p=0,j=1;p<n;j<<=1,m=p){
                for (p=0,i=n-j+1;i<=n;++i) tsa[++p]=i;
                for (i=1;i<=n;++i) if (sa[i]>j) tsa[++p]=sa[i]-j;
                for (i=0;i<=m;++i) sum[i]=0;
                for (i=1;i<=n;++i) ++sum[rank[tsa[i]]];
                for (i=1;i<=m;++i) sum[i]+=sum[i-1];
                for (i=n;i>=1;--i) sa[sum[rank[tsa[i]]]--]=tsa[i];
                for (p=trank[sa[1]]=1,i=2;i<=n;++i) trank[sa[i]]=cmp(sa[i],sa[i-1],j)?p:++p;
                memcpy(rank,trank,sizeof(int)*(n+1));
            }
        }
        int height[maxn];
        void get_height(){
            for (int h=0,i=1;i<=n;++i){
                if (rank[i]==1) continue;
                for (h?--h:0;s[i+h]==s[sa[rank[i]-1]+h];++h);
                height[rank[i]]=h;
            }
        }
        int fa[maxn];PII t[maxn];
        int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
        void get_ans(){
            splay.clear();
            for (int i=1;i<=n;++i){splay.insert(i,sa[i]);fa[i]=i;}
            for (int i=2;i<=n;++i) t[i-1]=make_pair(height[i],i);
            sort(t+1,t+n,greater<PII>());
            for (int i=1;i<=n-1;++i){
                int cur_height=t[i].first,cur_rank=t[i].second;
                if (!cur_height) break;
                int x=find(cur_rank),y=find(cur_rank-1);
                if (splay.size(x)>splay.size(y)) swap(x,y);
                splay.travel(x);
                for (int j=1;j<=cnt;++j){
                    int a=splay.greater(y,q[j]+l);
                    int b=splay.less(y,cur_height+l+q[j]+1);
                    ans+=(a+b-splay.size(y));
                    int c=splay.less(y,q[j]-l);
                    int d=splay.greater(y,q[j]-cur_height-l-1);
                    ans+=(c+d-splay.size(y));
                }
                splay.merge(y,x);fa[x]=y;
            }
        }
    }SA;
    void init(){
        scanf("%d%s",&l,s+1);n=strlen(s+1);
        SA.suffix_sort();SA.get_height();
    }
    void work(){
        SA.get_ans();
        printf("%lld
    ",ans);
    }
    int main(){
        init();
        work();
        return 0;
    }
    my code
  • 相关阅读:
    爬虫_监控某个元素所有事件
    Selenium_Selenium WebDriver 中鼠标和键盘事件分析及扩展
    Selenium_webdriver获取iframe子页面元素
    Java_Servlet 中文乱码问题及解决方案剖析
    thinkphp自动填充分析
    linux安装配置SVN并设置钩子
    HTTP协议提要
    一致性Hash算法(分布式算法)
    设计模式之:原型模式
    面向对象设计的五大原则
  • 原文地址:https://www.cnblogs.com/iamCYY/p/4730777.html
Copyright © 2020-2023  润新知