zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Kinect 开发 —— 硬件设备解剖
    Kinect 开发 —— 引言
    (转)OpenCV 基本知识框架
    OpenCV —— 摄像机模型与标定
    OpenCV —— 跟踪与运动
    OpenCV —— 图像局部与分割(二)
    OpenCV —— 图像局部与部分分割(一)
    OpenCV —— 轮廓
    OpenCV —— 直方图与匹配
    OpenCV —— 图像变换
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10884267.html
Copyright © 2011-2022 走看看