• HEOI2016/TJOI2016 字符串问题


    题目链接:戳我

    非常不好意思,因为想要排版,所以今天先只把代码贴出来,明天补题解。

    40pts暴力:直接暴力匹配

      #include<iostream>
      #include<cstring>
      #include<algorithm>
      #include<cmath>
      #include<cstdio>
      #define MAXN 100010
      using namespace std;
      int n,m;
      char s[MAXN];
      inline int solve(int l1,int r1,int l2,int r2)
      {
          int cur_ans=0,maxx=0;
          for(int i=l1;i<=r1;i++)
          {
              if(s[i]==s[l2+cur_ans]) cur_ans++;
              else cur_ans=0;
              maxx=max(maxx,cur_ans);
            //   printf("i=%d cur_ans=%d
    ",i,cur_ans);
              if(cur_ans>=r2-l2+1) break;
          }
          return maxx;
      }
      int main()
      {
          #ifndef ONLINE_JUDGE
          freopen("ce.in","r",stdin);
          #endif
          scanf("%d%d",&n,&m);
          scanf("%s",s+1);
          for(int i=1;i<=m;i++)
          {
              int l1,l2,r1,r2;
              scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
              printf("%d
    ",solve(l1,r1,l2,r2));
          }
          return 0;
      }
    

    开O2才能A的正解:SA+二分+二分+主席树
    复杂度是两只log的。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #define MAXN 200010
    using namespace std;
    int n,m,p,tot;
    int sa[MAXN],rnk[MAXN],tax[MAXN],tp[MAXN];
    int lg[MAXN],h[MAXN],rt[MAXN],st[MAXN][18];
    char s[MAXN];
    struct Node{int ls,rs,ff,cnt;}t[MAXN<<4];
    inline void build(int &x,int f,int l,int r,int k)
    {
        x=++tot;
        t[x]=t[f];
        t[x].cnt++;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(k<=mid) build(t[x].ls,t[f].ls,l,mid,k);
        else build(t[x].rs,t[f].rs,mid+1,r,k);
    }
    inline int query(int x,int f,int l,int r,int ll,int rr)
    {
        if(ll<=l&&r<=rr) return t[x].cnt-t[f].cnt;
        int mid=(l+r)>>1,cur_ans=0;
        if(ll<=mid) cur_ans+=query(t[x].ls,t[f].ls,l,mid,ll,rr);
        if(mid<rr) cur_ans+=query(t[x].rs,t[f].rs,mid+1,r,ll,rr);
        return cur_ans;
    }
    inline void q_sort()
    {
        for(int i=1;i<=m;i++) tax[i]=0;
        for(int i=1;i<=n;i++) tax[rnk[i]]++;
        for(int i=1;i<=m;i++) tax[i]+=tax[i-1];
        for(int i=n;i>=1;i--) sa[tax[rnk[tp[i]]]--]=tp[i];
    }
    inline void suffix_sort()
    {
        m=50,p=0;
        for(int i=1;i<=n;i++) rnk[i]=s[i]-'a'+1,tp[i]=i;
        q_sort();
        for(int w=1;p<n;m=p,w<<=1)
        {
            p=0;
            for(int i=1;i<=w;i++) tp[++p]=n+i-w;
            for(int i=1;i<=n;i++) if(sa[i]-w>0) tp[++p]=sa[i]-w;
            q_sort();
            swap(rnk,tp);
            p=rnk[sa[1]]=1;
            for(int i=2;i<=n;i++)
                rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
        }
    }
    inline void get_h()
    {
        int j,k=0;
        for(int i=1;i<=n;i++)
        {
            if(k) k--;
            int j=sa[rnk[i]-1];
            while(s[i+k]==s[j+k]) k++;
            h[rnk[i]]=k;
        }
    }
    inline void st_init()
    {
        for(int i=1;i<=n;i++) st[i][0]=h[i];
        for(int j=1;j<=17;j++)
            for(int i=1;i<=n;i++)
                st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    }
    inline int st_query(int l,int r)
    {
        if(l==r) return 0x3f3f3f3f;
        l++;
        return min(st[l][lg[r-l+1]],st[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
    }
    inline bool check(int x,int l1,int r1,int l2,int r2)
    {
        int L,R,l=1,r=rnk[l2],ans=r;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(st_query(mid,rnk[l2])>=x) ans=mid,r=mid-1;
            else l=mid+1;
        }
        L=ans;
        l=rnk[l2],r=n,ans=l;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(st_query(rnk[l2],mid)>=x) ans=mid,l=mid+1;
            else r=mid-1;
        }
        R=ans;
        return query(rt[R],rt[L-1],1,n,l1,r1-x+1)==0?false:true;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d",&n,&m);
        scanf("%s",s+1);
        for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
        suffix_sort();
        get_h();
        st_init();
        for(int i=1;i<=n;i++) build(rt[i],rt[i-1],1,n,sa[i]);
        for(int i=1;i<=m;i++)
        {
            int l1,l2,r1,r2;
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            int ans=0;
            int l=0,r=min(r1-l1,r2-l2)+1;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(check(mid,l1,r1,l2,r2)) ans=mid,l=mid+1;
                else r=mid-1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    转:wap1.1和wap2.0的比较~
    转:alidateRequest=false 在.Net 4.0 中不管用
    ASP.NET页面实时进行GZIP压缩优化
    转:WAP1.0 和 WAP2.0 支持的标签区别
    [转载]利用vs.net快速开发windows服务(c#)
    CSS3选择器
    AD10 多层板设计错误解决
    ASP如何获取客户端真实IP地址
    javascript模拟滚动条实现代码(3)
    最近工作中的小细节
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10884267.html
Copyright © 2020-2023  润新知