• POJ 3294 二分找超过一半字符串中存在的子串


    题目大意:

    给定n个字符串,求出现在不小于k/2个字符串中的最长子串。 

    二分找对应子串长度的答案,将所有字符串链接成一个长字符串求后缀数组,记录每一个位置本属于第几个字符串,利用height查询的时候,

    根据记录的位置不断判断是否出现重复的字符串是在同一个字符串内的

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <iostream>
      5 using namespace std;
      6 typedef long long ll;
      7 const int N = 200010;
      8 int r[N] , sa[N] , rank[N] , height[N];
      9 int K , wa[N] , wb[N] , wv[N] , wsf[N];
     10 int cmp(int *r , int a , int b , int l){return r[a]==r[b]&&r[a+l]==r[b+l];}
     11 void da(int *r , int *sa , int n , int m)
     12 {
     13     int i,j,p,*x=wa,*y=wb,*t;
     14     for(i=0;i<m;i++)wsf[i]=0;
     15     for(i=0;i<n;i++)wsf[x[i]=r[i]]++;
     16     for(i=1 ; i<m ; i++) wsf[i]+=wsf[i-1];
     17     for(i=n-1;i>=0;i--) sa[--wsf[x[i]]]=i;
     18     for(j=1,p=1;p<n;j*=2,m=p){
     19         for(p=0,i=n-j;i<n;i++) y[p++]=i;
     20         for(i=0;i<n;i++) if(sa[i]>=j)y[p++]=sa[i]-j;
     21         for(i=0;i<n;i++) wv[i]=x[y[i]];
     22         for(i=0;i<m;i++) wsf[i]=0;
     23         for(i=0;i<n;i++) wsf[wv[i]]++;
     24         for(i=1;i<m;i++) wsf[i]+=wsf[i-1];
     25         for(i=n-1;i>=0;i--) sa[--wsf[wv[i]]]=y[i];
     26         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
     27             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
     28     }
     29     return;
     30 }
     31 void callHeight(int *r , int *sa , int n)
     32 {
     33     int i,j,k=0;
     34     for(i=1;i<=n;i++) rank[sa[i]]=i;
     35     for(i=0;i<n;height[rank[i++]]=k)
     36         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
     37     return;
     38 }
     39 #define ll long long
     40 int n , len , pos[105][2] , dif , mp[N];
     41 bool vis[105];
     42 char s[105][1005] , all[N];
     43 vector<int> ans , tmp;
     44 bool check(int mid)
     45 {
     46     tmp.clear();
     47     bool flag = false;
     48     memset(vis , 0 , sizeof(vis));
     49     int cnt = 1 , rec = sa[0];
     50     vis[sa[0]] = true;
     51     for(int i=1 ; i<len ; i++){
     52         if(height[i]<mid){
     53             if(cnt>n/2){
     54                 tmp.push_back(rec);
     55                 flag = true;
     56             }
     57             memset(vis , 0 , sizeof(vis));
     58             cnt = 1 , vis[mp[sa[i]]] = true , rec = sa[i];
     59         }
     60         else{
     61             if(!vis[mp[sa[i]]]){
     62                 vis[mp[sa[i]]] = true;
     63                 cnt++;
     64                 rec = sa[i];
     65             }
     66         }
     67     }
     68     if(flag) ans = tmp;
     69     return flag;
     70 }
     71 int bin_search()
     72 {
     73     int l=0 , r=1000 , ans=0 , mid;
     74     while(l<=r){
     75         mid = (l+r)>>1;
     76         if(check(mid)) l=mid+1 , ans=mid;
     77         else r=mid-1;
     78     }
     79     return ans;
     80 }
     81 int main()
     82 {
     83    // freopen("a.in" , "r" , stdin);
     84     bool flag = false;
     85     while(scanf("%d" , &n) , n){
     86         if(flag) puts("");
     87         flag = true;
     88         len = 0 , dif = 27;
     89         for(int i=0 ; i<n ; i++){
     90             scanf("%s" , s[i]);
     91             for(int j=0 ; j<strlen(s[i]) ; j++) all[len] = s[i][j] , mp[len]=i+1 , r[len++] = s[i][j]-'a'+1;
     92             pos[i][0] = len;
     93             all[len] = '*';
     94             mp[len]=i+1 , r[len++] = dif++;
     95         }
     96         r[len-1] = 0;
     97         da(r , sa , len , dif);
     98        // for(int i=0 ; i<len ; i++) cout<<"i: "<<i<<" "<<sa[i]<<endl;
     99         callHeight(r , sa , len-1);
    100         int ret = bin_search();
    101         if(!ret) puts("?");
    102         else{
    103             for(int i=0 ; i<ans.size() ; i++){
    104                 for(int j=ans[i] , t=0 ; t<ret ; j++ , t++) printf("%c" , all[j]);
    105                 puts("");
    106             }
    107         }
    108     }
    109 }
  • 相关阅读:
    《JavaScript高级程序设计》阅读笔记(十七):事件
    Windows 8 Consumer Preview版升级到 Release Preview 版后Metro应用(html5+JavaScript版)修改小结
    [转]linux netstat命令查看端口是否占用
    jQuery 1.8 Release版本发布了
    分享一个用原生JavaScript写的带缓动效果的图片幻灯
    [转]Javascript 绝句
    win8 下 WCF "Could not load type 'System.ServiceModel.Activation.HttpModule'" 错误解决方案
    【转】WEB APP 不同设备屏幕下图片适应分辨率
    给你的JS类库加上命名空间和扩展方法:jutil第一次重构
    Javascript图像处理之将彩色图转换成灰度图
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/5150118.html
Copyright © 2020-2023  润新知