• 一些字符串的题


    1.BZOJ 2434 阿狸的打字机

    AC自动机+树状数组

    //Twenty
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<queue> 
    using namespace std;
    const int maxn=100000+29;
    char s[maxn];
    int tot,n,m,ecnt,fi[maxn],nx[maxn],tt[maxn],fir[maxn],nxt[maxn],to[maxn];
    int ls[maxn],le[maxn],dfs_clock,sum[maxn],cnt,num[maxn],ans[maxn],xbh[maxn];
    int qry(int x){
        int res=0; 
        for(int i=x;i>0;i-=(i&(-i))) 
        res+=sum[i]; 
        return res;
    } 
    void addsum(int x,int v){
       for(int i=x;i<=tot;i+=(i&(-i))) 
       sum[i]+=v;
    }
    struct Node{
        int l,r,id,bh;
    }qs[maxn];
    struct node{
        node *s[26],*fail,*fa;
        int id,bh;
        node(){
            for(int i=0;i<26;i++) s[i]=NULL; fail=NULL; fa=NULL; 
        }
    }*root,*now,*tep;
    void add(int u,int v,int k){
        nx[++ecnt]=fi[u];fi[u]=ecnt;tt[ecnt]=v; num[ecnt]=k;
    }
    void add_edge(int u,int v){
        nxt[++cnt]=fir[u]; fir[u]=cnt; to[cnt]=v;
    }
    void build(){
        root=new node(); 
        root->bh=++tot;
        now=root;
        for(int i=0;s[i]!='';i++){
            if(s[i]=='P') {now->id=++n; xbh[n]=tot; }
            else if(s[i]=='B') now=now->fa ;
            else{
                int c=s[i]-'a';
                if(now->s[c]==NULL){
                    tep=new node();
                    tep->bh=++tot;
                    now->s[c]=tep;
                    now->s[c]->fa=now;
                }
                now=now->s[c];        
            }
        }
    }
    void dfs(int x){
        ls[x]=++dfs_clock;
        for(int i=fir[x];i;i=nxt[i]){
            dfs(to[i]);
        }
        le[x]=dfs_clock;
    }
    int query(int x){
        return qry(le[x])-qry(ls[x]-1);
    }
    void get_fail(){
        queue<node*>que;
        que.push(root); 
        while(!que.empty() ){
            now=que.front(); que.pop();
            for(int i=0;i<26;i++)
             if(now->s[i]!=NULL){
                 if(now==root) now->s[i]->fail=root;
                 else{
                     tep=now->fail;
                     while(tep->s[i]==NULL&&tep->fail!=NULL) tep=tep->fail;
                     if(tep->s[i]) now->s[i]->fail =tep->s[i];
                     else now->s[i]->fail=root;
                 }
                 add_edge(now->s[i]->fail->bh,now->s[i]->bh);
                 que.push(now->s[i]);
             } 
        }
    }
    void travel(){
        now=root;
        for(int i=0;s[i]!='';i++){
            if(s[i]=='P') {
                if(fi[now->id]){
                    for(int j=fi[now->id];j;j=nx[j]){
                        ans[num[j]]=query(xbh[tt[j]]);
                    }
                }
            }
            else if(s[i]=='B') {addsum(ls[now->bh],-1); now=now->fa ;}
            else{
                int c=s[i]-'a';
                now=now->s[c];
                addsum(ls[now->bh],1);
            }
        }
    }
    int main(){ 
        scanf("%s",s);
        build();
        get_fail();
        dfs(1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&qs[i].l,&qs[i].r);
            add(qs[i].r,qs[i].l,i); qs[i].id=i;
        }
        travel();
        for(int i=1;i<=m;i++)
         printf("%d
    ",ans[i]);
        return 0;
    }
    BZOJ 2434 阿狸的打字机

    2.hash UVA 4513口吃的外星人

    紫书原题

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    const int maxn=4e5+29;
    const int x=123;
    char s[maxn];
    int pos,m,ans,n,rak[maxn],hs[maxn],xl[maxn],has[maxn];
    using namespace std;
    bool cmp(const int &a,const int &b){
      return has[a]==has[b]?a<b:has[a]<has[b];
    }
    bool check(int l){
      int c=0; pos=-1;
      for(int i=0;i<n-l+1;i++){
        rak[i]=i;
        has[i]=hs[i]-hs[i+l]*xl[l];
      }
      sort(rak,rak+n-l+1,cmp);
      for(int i=0;i<n-l+1;i++){
        if(i==0||has[rak[i]]!=has[rak[i-1]]) c=0;
        if(++c>=m) pos=max(pos,rak[i]);
      }
      return pos>-1;
    }
    int main()
    {
       //freopen(".in","r",stdin);
       //freopen(".out","w",stdout);
       while(scanf("%d",&m)){
           if(!m) break;
       scanf("%s",s);
       n=strlen(s);
       hs[n]=0; 
       for(int i=n-1;i>=0;i--) 
       hs[i]=hs[i+1]*x+(s[i]-'a');
       xl[0]=1; 
       for(int i=1;i<=n;i++) xl[i]=xl[i-1]*x;
       if(!check(1)) printf("none
    ");
       else{
        int l=1,r=n+1;
        while(r-l>1){
          int mid=l+((r-l)>>1);
          if(check(mid)) l=mid;
          else r=mid;
        }
        check(l);
        printf("%d %d
    ",l,pos);
       }
       }
       return 0;
    }
    口吃的外星人

    3.BZOJ 2342 双倍回文

    manacher 没想开 手写了一颗treap

    BZOJ 2342 双倍回文

    4.BZOJ 3230 相似子串

    后缀数组 

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn=100000+50;
    typedef long long LL; //LL真的害死人啊 
    int m=150,n,Q,saz[maxn],saf[maxn],rakz[maxn],rakf[maxn];
    int hz[maxn],hf[maxn],stz[maxn][20],stf[maxn][20];
    char ch[maxn],sz[maxn*2],sf[maxn*2];
    LL sum[maxn];
    inline bool mp(int *y,int p,int q,int k){
        int o0=p+k>=n?-1:y[p+k];
        int o1=q+k>=n?-1:y[q+k];
        return o0==o1&&y[p]==y[q];
    }
    void make_hight(char *s,int *hight,int *sa,int st[][20],int *rank){
       for(int i=0;i<n;i++) rank[sa[i]]=i;
        int k=0;
        for(int i=0;i<n;i++){
            //st[i][0]=n-sa[i]; //st[i][j]表示i到i+2^j而不能是i到i+2^j-1 否则。。 
            if(!rank[i]) continue;
            if(k) k--;
            int j=sa[rank[i]-1];
            while(s[j+k]==s[i+k]) k++;
            hight[rank[i]]=k;
            st[rank[i]-1][0]=k;
        }
       for(int j=1;j<=20;j++)
        for(int i=0;i+(1<<j)<n;i++)
         st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    }
    void make_sa(char *s,int *sa,int st[][20],int *rank,int *hight){
       static int t1[maxn],t2[maxn],c[maxn];
        int i,*x=t1,*y=t2;
        for(i=0;i<m;i++) c[i]=0;
        for(i=0;i<n;i++) c[x[i]=s[i]]++;
        for(i=1;i<m;i++) c[i]+=c[i-1];
        for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 
        for(int k=1;k<=n;k<<=1){ 
          int p=0;
          for(i=n-k;i<n;i++) y[p++]=i;
          for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
          for(i=0;i<m;i++) c[i]=0;
          for(i=0;i<n;i++) c[x[y[i]]]++;
          for(i=1;i<m;i++) c[i]+=c[i-1];
          for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
          swap(x,y);p=1;x[sa[0]]=0;
          for(i=1;i<n;i++)  
          x[sa[i]]=mp(y,sa[i],sa[i-1],k)?p-1:p++;
          if(p>=n) break;
           m=p;
        }
        make_hight(s,hight,sa,st,rank);
    }
    void make_sum(){
       sum[0]=n-saz[0];
       for(int i=1;i<n;i++)
         sum[i]=sum[i-1]+n-saz[i]-hz[i];
    }
    int ef(LL x,int &rel,int &rer){
       int l=1,r=n;
       while(l<=r){
            int mid=(l+r)>>1;
         if(sum[mid-1]>=x) rel=mid-1,r=mid-1;
         else l=mid+1; 
       }
       rer=n-(sum[rel]-x)-1;
       rel=saz[rel];
    }
    LL RMQ(int st[][20],int *sa,int l,int r){
       int k=0;
       if(l==r) return n-sa[l];
       while(l+(1<<k)<=r) k++;
       if(k) k--;
       return (LL)min(st[l][k],st[r-(1<<k)][k]);
    }
    LL qry(LL l,LL r){
        int l1,r1,l2,r2;
        ef(l,l1,r1);
        ef(r,l2,r2);
        LL ans1=(LL)min(r1-l1+1,r2-l2+1);
        LL ans2=(LL)min(r1-l1+1,r2-l2+1);
        l1=rakz[l1]; l2=rakz[l2];
        if(l1>l2) swap(l1,l2);
        ans1=min(ans1,RMQ(stz,saz,l1,l2));
        r1=rakf[n-r1-1]; r2=rakf[n-r2-1];
        if(r1>r2) swap(r1,r2);
        ans2=min(ans2,RMQ(stf,saf,r1,r2));
        return ans1*ans1+ans2*ans2;
    }
    int main()
    {
       scanf("%d%d",&n,&Q);
       scanf("%s",sz);
       for(int i=0;i<n;i++) sf[i]=sz[n-i-1];
       make_sa(sz,saz,stz,rakz,hz);
       make_sa(sf,saf,stf,rakf,hf);
       make_sum();
       while(Q--){
          LL ql,qr;
          scanf("%lld%lld",&ql,&qr);
          if(ql>sum[n-1]||qr>sum[n-1]) printf("-1
    ");
          else printf("%lld
    ",qry(ql,qr));
       }
       return 0;
    }
    BZOJ 3230 相似子串

    5.BZOJ 3238 差异

    后缀数组 单调栈优化

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack> 
    const int maxn=100000+5;
    typedef long long LL;
    char s[maxn];
    int mi=1e9+7,m=150,n,sa[maxn],hight[maxn],rank[maxn],l[maxn],r[maxn];
    using namespace std;
    void make_hight(){
        for(int i=0;i<n;i++) rank[sa[i]]=i;
        int k=0;
        for(int i=0;i<n;i++){
            if(!rank[i]) continue;
            if(k) k--;
            int j=sa[rank[i]-1];
            while(s[i+k]==s[j+k]) k++;
            hight[rank[i]]=k;
        }
    }
    bool mp(int *y,int a,int b,int k){
        int o1=(a+k)>=n?-1:y[a+k];
        int o2=(b+k)>=n?-1:y[b+k];
        return (o1==o2&&y[a]==y[b]);
    }
    void make_sa(){
        static int t1[maxn],t2[maxn],c[maxn];
        int *x=t1,*y=t2,i,k;
        for(i=0;i<m;i++) c[i]=0;
        for(i=0;i<n;i++) c[x[i]=s[i]]++;
        for(i=1;i<m;i++) c[i]+=c[i-1];
        for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
        for(k=1;k<=n;k<<=1){
        int p=0;
        for(i=n-k;i<n;i++) y[p++]=i;
        for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 
        for(i=0;i<m;i++) c[i]=0;
        for(i=0;i<n;i++) c[x[y[i]]]++;
        for(i=1;i<m;i++) c[i]+=c[i-1];
        for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
        swap(x,y); p=1; x[sa[0]]=0;
        for(i=1;i<n;i++)
        x[sa[i]]=mp(y,sa[i],sa[i-1],k)?p-1:p++;
        if(p>=n) break; 
        m=p;
        }
        make_hight();
    }
    LL work(){
        LL ans=0,res=0;
        int now;
        for(int i=n;i>=1;i--){
            ans+=(LL)i*(LL)(n-1);
        }
        stack<int>que; que.push(0);
        for(int i=1;i<n;i++){
            while(!que.empty()&&(hight[now=que.top()]>hight[i])){
                que.pop();
            }
            if(!que.empty()){
                now=que.top();
                l[i]=now;
            }
            else l[i]=-1;
            que.push(i);     
        }  
        while(!que.empty())  que.pop();
        for(int i=n-1;i>0;i--){
            while(!que.empty()&&(hight[now=que.top()]>=hight[i])){
                que.pop();
            }
            if(!que.empty()){
                now=que.top();
                r[i]=now;
            }
            else r[i]=n;
            que.push(i);     
        }  
        for(int i=0;i<n;i++)
        res+=(LL)(i-l[i])*(r[i]-i)*hight[i];
        return ans-res*2;
    }
    int main()
    {
       freopen("b.in","r",stdin);
       freopen("b.out","w",stdout);
       scanf("%s",s);
       n=strlen(s); //m=n;
       //for(int i=0;i<n;i++) {int smg=s[i]; mi=min(mi,smg);}
       make_sa();
       printf("%lld
    ",work());
       return 0;
    }
    BZOJ 3238 差异
  • 相关阅读:
    均匀分布
    深度学习0开始
    w3 parse a url
    【Docker学习之一】初始Docker
    【Spring Cloud学习之六】断路器-Hystrix
    【Spring Cloud学习之五】配置中心
    【Spring Cloud学习之四】Zuul网关
    【Spring Cloud学习之三】负载均衡
    【Spring Cloud学习之二】服务注册和发现
    【Spring Cloud学习之一】微服务架构
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7475139.html
Copyright © 2020-2023  润新知