• 【BZOJ】【2946】【POI2000】公共串


    后缀数组


      好感动,复习了下后缀数组居然写出来了……(感谢ykz大神)

      求最长公共子串……WA了一发是因为:【不同字符串之间要用不同的特殊字符隔开】否则就会匹配到相同→_→比如都是aaa结尾,如果用相同特殊字符就会使得最长公共子串变成aaa#这样子……

      1 /**************************************************************
      2     Problem: 2946
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:60 ms
      7     Memory:4104 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 2946
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstring>
     14 #include<cstdlib>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 #define pb push_back
     21 using namespace std;
     22 typedef long long LL;
     23 inline int getint(){
     24     int r=1,v=0; char ch=getchar();
     25     for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
     26     for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
     27     return r*v;
     28 }
     29 const int N=1e5+10,INF=~0u>>2;
     30 /*******************template********************/
     31 int sa[N],rank[N],height[N],belong[N],wa[N],wb[N],c[N],n,m;
     32 int len[6];
     33 char s[N];
     34 bool cmp(int *r,int a,int b,int l){
     35     return r[a]==r[b] && r[a+l]==r[b+l];
     36 }
     37 void DA(char *s,int *sa,int n,int m){
     38     int i,j,p,*x=wa,*y=wb;
     39     rep(i,m) c[i]=0;
     40     rep(i,n) c[x[i]=s[i]]++;
     41     F(i,1,m-1) c[i]+=c[i-1];
     42     D(i,n-1,0) sa[--c[x[i]]]=i;
     43     for(j=1,p=0;p<n;j<<=1,m=p){
     44         for(p=0,i=n-j;i<n;i++) y[p++]=i;
     45         rep(i,n) if (sa[i]>=j) y[p++]=sa[i]-j;
     46  
     47         rep(i,m) c[i]=0;
     48         rep(i,n) c[x[y[i]]]++;
     49         F(i,1,m-1) c[i]+=c[i-1];
     50         D(i,n-1,0) sa[--c[x[y[i]]]]=y[i];
     51         swap(x,y); p=1; x[sa[0]]=0;
     52         F(i,1,n-1) x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p-1 : p++;
     53     }
     54 }
     55 void calheight(char *s,int *sa,int n){
     56     int k=0;
     57     F(i,1,n) rank[sa[i]]=i;
     58     rep(i,n){
     59         if (k) k--;
     60         int j=sa[rank[i]-1];
     61         while(s[i+k]==s[j+k]) k++;
     62         height[rank[i]]=k;
     63     }
     64 }
     65 int main(){
     66 #ifndef ONLINE_JUDGE
     67     freopen("2946.in","r",stdin);
     68     freopen("2946.out","w",stdout);
     69 #endif
     70     n=getint();int l=0;
     71     F(i,1,n){
     72         scanf("%s",s+l);
     73         len[i]=strlen(s)-l;
     74         l=strlen(s);
     75         s[l++]='a'-n+i;
     76     }
     77     rep(i,l) s[i]=s[i]-'a'+10;
     78     l--;
     79     DA(s,sa,l+1,40);
     80     calheight(s,sa,l);
     81     int tmp=1;
     82     rep(i,l){
     83         if (s[i]<10) {tmp++;continue;}
     84         belong[rank[i]]=tmp;
     85     }
     86  
     87  
     88     bool vis[6]={0};
     89     int L=0,R=2000,mid,cnt,ans=0;
     90     while(L<=R){
     91         mid=(L+R)>>1;bool sign=0;
     92         cnt=0; memset(vis,0,sizeof vis);
     93         F(i,n,l){
     94             if (height[i]<mid){
     95                 cnt=1;memset(vis,0,sizeof vis);
     96                 vis[belong[i]]=1; continue;
     97             }
     98             if (!vis[belong[i]]) vis[belong[i]]=1,cnt++;
     99             if (cnt==n) sign=1;
    100         }
    101         if (sign) ans=mid,L=mid+1;
    102         else R=mid-1;
    103     }
    104     printf("%d
    ",ans);
    105     return 0;
    106 }
    View Code

    2946: [Poi2000]公共串

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 160  Solved: 67
    [Submit][Status][Discuss]

    Description

     
           给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
    任务:
    l        读入单词
    l        计算最长公共子串的长度
    l        输出结果
     

    Input

     
    文件的第一行是整数 n1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000
     

    Output

    仅一行,一个整数,最长公共子串的长度。
     

    Sample Input

    3
    abcb
    bca
    acbc

    Sample Output

    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    双日历时间段选择控件—daterangepicker(汉化版)
    vue elementui table表格展开行每次只展开一行
    vue-pdf PDF文件预览
    async await
    vuex发送axios请求
    jq调用浏览器下载文件 window.open()
    禁止页面右键、选择、F12操作
    vue 点击一条消息跳转相应的页面且对应相应的大模块和办理状态
    vue-infinite-scroll 滚动加载下一页
    填写流程当前登录人可以填写除自己可填项外还可看到他前面经办人相关填写的内容,且经办人后面的不可见
  • 原文地址:https://www.cnblogs.com/Tunix/p/4399355.html
Copyright © 2020-2023  润新知