zoukankan      html  css  js  c++  java
  • poj1226 Substrings

    2333

    这个就是把每一个串正反连起来,然后所有串连起来,注意中间加上分割的分开(应该开的比z大,而且蛋疼的我写int)

    然后搞出后缀数组,二分一个答案,然后再height数组判断一下就好了

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 #define N 100005
      5 #define inf 0x3f3f3f3f
      6 #define LL long long
      7 #define eps 1e-8
      8 using namespace std;
      9 inline int ra()
     10 {
     11     int x=0,f=1; char ch=getchar();
     12     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     13     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     14     return x*f;
     15 }
     16 
     17 const int maxn=10005;
     18 
     19 int sa[2][maxn],rank[2][maxn],v[maxn],height[maxn],p=0,q=1;
     20 int n,len,id[maxn];
     21 int a[maxn];
     22 bool vis[105];
     23 
     24 void cal_sa(int sa[N], int rank[N], int Sa[N], int Rank[N], int k)
     25 {
     26     for (int i=1; i<=n; i++) v[rank[sa[i]]]=i;
     27     for (int i=n; i>=1; i--) if (sa[i]>k) Sa[v[rank[sa[i]-k]]--]=sa[i]-k;
     28     for (int i=n-k+1; i<=n; i++) Sa[v[rank[i]]--]=i;
     29     for (int i=1; i<=n; i++) Rank[Sa[i]]=Rank[Sa[i-1]]+(rank[Sa[i]]!=rank[Sa[i-1]] || rank[Sa[i]+k]!=rank[Sa[i-1]+k]);
     30 }
     31 void get_height()
     32 {
     33     int k=0;
     34     for (int i=1; i<=n; i++)
     35     {
     36         if (rank[p][i]==1) height[1]=0;
     37         else
     38         {
     39             int j=sa[p][rank[p][i]-1];
     40             while (a[j+k]==a[i+k]) k++;
     41             height[rank[p][i]]=k;
     42             if (k) k--;
     43         }
     44     }
     45 }
     46 void work()
     47 {
     48     for (int i=1; i<=n; i++) v[a[i]]++;
     49     for (int i=1; i<=300; i++) v[i]+=v[i-1];
     50     for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i;
     51     for (int i=1; i<=n; i++) rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
     52     for (int k=1; k<n; k<<=1,swap(p,q)) cal_sa(sa[p],rank[p],sa[q],rank[q],k);
     53     get_height();
     54 }
     55 
     56 bool check(int L)
     57 {
     58     int tot=0; memset(vis,0,sizeof(vis));
     59     for (int i=2; i<=n; i++)
     60     {
     61         if (height[i]<L)
     62         {
     63             tot=0; memset(vis,0,sizeof(vis));
     64             continue;
     65         }
     66         if (!vis[id[sa[p][i-1]]]) vis[id[sa[p][i-1]]]=1,tot++;
     67         if (!vis[id[sa[p][i]]]) vis[id[sa[p][i]]]=1,tot++;
     68         if (tot>=len) return 1;
     69     }
     70     return 0;
     71 }
     72 void solve()
     73 {
     74     int l=0,r=n,ans=0;
     75     while (l<=r)
     76     {
     77         int mid=l+r>>1;
     78         if (check(mid)) ans=mid,l=mid+1; else r=mid-1;
     79     }
     80     printf("%d
    ",ans);
     81 }
     82 int main(int argc, char const *argv[])
     83 {
     84     int T=ra();
     85     while (T--)
     86     {
     87         memset(v,0,sizeof(v)); n=ra(); len=0;
     88         for (int i=1; i<=n; i++)
     89         {
     90             char ch[105]; scanf("%s",ch+1);
     91             for (int j=1; j<=strlen(ch+1); j++)
     92                 a[++len]=ch[j],id[len]=i;
     93             a[++len]=150+(i-1)*2,id[len]=i;
     94             for (int j=strlen(ch+1); j>=1; j--)
     95                 a[++len]=ch[j],id[len]=i;
     96             a[++len]=150+(i-1)*2+1,id[len]=i;
     97         }
     98         swap(n,len); work();
     99         solve();
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6642213.html
Copyright © 2011-2022 走看看