zoukankan      html  css  js  c++  java
  • tsinsenA1484. two strings(罗干)

    http://www.tsinsen.com/A1484

      在线插入并不好做,我们将所有操作离线,变为删除操作。

      每次询问的时候对于当前B串所在起始位置及其长度向上向下二分,然后查询区间内合法的当前A串内的匹配点即可。用树状数组维护。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxlen=200015,maxm=200015,maxk=20;
    int tmp,sta,eda,stb,edb,len,m,w[maxm];
    char a[maxlen*2],b[maxlen*2],s[maxlen];
    struct Tbit{
        int T[maxlen];
        void modify(int x,int v){for (int p=x;p<=len;p+=p&-p) T[p]+=v;}
        int query(int l,int r){
            int res=0;
            for (int p=l-1;p>=1;p-=p&-p) res-=T[p];
            for (int p=r;p>=1;p-=p&-p) res+=T[p];
            return res;
        }
    }bit;
    struct Tsuffix_array{
        int sum[maxlen],sa[maxlen],rank[maxlen],tsa[maxlen],trank[maxlen];
        bool cmp(int i,int j,int l){
            if (i+l>len||j+l>len) 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<=len;++i) ++sum[rank[i]=s[i]];
            for (i=1;i<=m;++i) sum[i]+=sum[i-1];
            for (i=len;i>=1;--i) sa[sum[rank[i]]--]=i;
            for (p=0,j=1;p<len;j<<=1,m=p){
                for (p=0,i=len-j+1;i<=len;++i) tsa[++p]=i;
                for (i=1;i<=len;++i) if (sa[i]>j) tsa[++p]=sa[i]-j;
                for (i=0;i<=m;++i) sum[i]=0;
                for (i=1;i<=len;++i) ++sum[rank[tsa[i]]];
                for (i=1;i<=m;++i) sum[i]+=sum[i-1];
                for (i=len;i>=1;--i) sa[sum[rank[tsa[i]]]--]=tsa[i];
                for (p=trank[sa[1]]=1,i=2;i<=len;++i) trank[sa[i]]=cmp(sa[i],sa[i-1],j)?p:++p;
                memcpy(rank,trank,sizeof(int)*(len+1));
            }
        }
        int height[maxlen];
        void get_height(){
            for (int h=0,i=1;i<=len;++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 fmn[maxk][maxlen];
        void prepare(){
            for (int i=2;i<=len;++i) fmn[0][i]=height[i];
            for (int k=1;k<maxk;++k)
                for (int j=1<<k;j<=len;++j)
                    fmn[k][j]=min(fmn[k-1][j],fmn[k-1][j-(1<<(k-1))]);
        }
        int LCP(int x,int y){
            if (++x>y) return len-sa[y]+1;
            int k=log2(y-x+1);
            return min(fmn[k][y],fmn[k][x+(1<<k)-1]);
        }
        int calc_up(int pos,int lim){
            int l=1,r=pos,res;
            while (l<=r){
                int mid=(l+r)>>1;
                LCP(mid,pos)>=lim?r=(res=mid)-1:l=mid+1;
            }
            return res;
        }
        int calc_low(int pos,int lim){
            int l=pos,r=len,res;
            while (l<=r){
                int mid=(l+r)>>1;
                LCP(pos,mid)>=lim?l=(res=mid)+1:r=mid-1;
            }
            return res;
        }
        int query(){
            int pos=rank[tmp+stb],lim=edb-stb+1;
            return bit.query(calc_up(pos,lim),calc_low(pos,lim));
        }
    }SA;
    void init(){
        sta=stb=maxlen;scanf("%s%s%d",a+maxlen,b+maxlen,&m);
        eda=maxlen+strlen(a+maxlen)-1;edb=maxlen+strlen(b+maxlen)-1;
        for (int i=1;i<=m;++i){
            char c[2];scanf("%d",&w[i]);
            switch (w[i]){
                case 1:scanf("%s",c);a[--sta]=c[0];break;
                case 2:scanf("%s",c);a[++eda]=c[0];break;
                case 3:scanf("%s",c);b[--stb]=c[0];break;
                case 4:scanf("%s",c);b[++edb]=c[0];break;
                default:break;
            }
        }
        for (int i=sta;i<=eda;++i) a[i-sta+1]=a[i];a[eda-sta+2]=0;eda=eda-sta+1;sta=1;
        for (int i=stb;i<=edb;++i) b[i-stb+1]=b[i];b[edb-stb+2]=0;edb=edb-stb+1;stb=1;
        for (int i=1;i<=eda;++i) s[++len]=a[i];s[++len]='#';tmp=len;
        for (int i=1;i<=edb;++i) s[++len]=b[i];s[len+1]=0;
    }
    vector<int> ans;
    void work(){
        SA.suffix_sort();SA.get_height();SA.prepare();
        for (int i=1;i<=eda-edb+1;++i) bit.modify(SA.rank[i],1);
        for (int tim=m;tim>=1;--tim)
            switch (w[tim]){
                case 1:if (eda-sta+1>=edb-stb+1) bit.modify(SA.rank[sta],-1);++sta;break;
                case 2:if (eda-sta+1>=edb-stb+1) bit.modify(SA.rank[eda-(edb-stb+1)+1],-1);--eda;break;
                case 3:++stb;if (eda-sta+1>=edb-stb+1) bit.modify(SA.rank[eda-(edb-stb+1)+1],1);break;
                case 4:--edb;if (eda-sta+1>=edb-stb+1) bit.modify(SA.rank[eda-(edb-stb+1)+1],1);break;
                case 5:ans.push_back(SA.query());break;
            }
        for (int i=ans.size()-1;i>=0;--i) printf("%d
    ",ans[i]);
    }
    int main(){
        init();
        work();
        return 0;
    }
    my code
  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/iamCYY/p/4730802.html
Copyright © 2011-2022 走看看