zoukankan      html  css  js  c++  java
  • bzoj2534: Uva10829L-gap字符串

    Description

    有一种形如uvu形式的字符串,其中u是非空字符串,且V的长度正好为L,那么称这个字符串为L-Gap字符串
    给出一个字符串S,以及一个正整数L,问S中有多少个L-Gap子串.

    Input

    第一行一个数字L
    第二行一个字符串S

     

    Output

     

    一个数字表示S中有多少个L-Gap子串.

     

    Sample Input


    3
    aabbaa



    Sample Output


    2

    Hint

    S的长度不超过50000,L<=10
     
    题解:http://www.cnblogs.com/iamCYY/p/4730777.html
    Orz CYY
     
    code:
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #define maxn 50050
      7 using namespace std;
      8 char ch,s[maxn];
      9 int n,l,ans;
     10 int fa[maxn],root[maxn],list[maxn],cnt,que[maxn];
     11 int SA[maxn],rank[maxn],height[maxn],sum[maxn],t1[maxn],t2[maxn];
     12 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
     13 struct Splay{
     14     int tot,son[maxn][2],fa[maxn],siz[maxn],val[maxn];
     15     void init(){
     16         for (int i=1;i<=n;i++) siz[++tot]=1;
     17         for (int i=1;i<=n;i++) val[i]=SA[i];
     18     }
     19     int which(int x){return son[fa[x]][1]==x;}
     20     void update(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;}
     21     void rotate(int x){
     22         int y=fa[x],d=which(x),dd=which(y);
     23         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y];
     24         if (fa[x]) son[fa[x]][dd]=x;
     25         son[x][d^1]=y,fa[y]=x,update(y),update(x);
     26     }
     27     void splay(int x){
     28         while (fa[x]){
     29             if (!fa[fa[x]]) rotate(x);
     30             else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x);
     31             else rotate(x),rotate(x);    
     32         }
     33         root[find(x)]=x;
     34     }
     35     void insert(int root,int x){
     36         int f,t;
     37         for (f=t=root;t;t=son[t][val[x]>val[t]]) f=t;
     38         son[f][val[x]>val[f]]=x,fa[x]=f,splay(x);
     39     }
     40     void merge(int x){while (cnt) insert(root[x],que[cnt--]);}
     41     int find_pre(int root,int v){
     42         int x,t=0;
     43         for (x=root;x;val[x]<v?t=x,x=son[x][1]:x=son[x][0]);
     44         if (t) splay(t);
     45         return t?siz[son[t][0]]+1:0;
     46     }
     47     int find_next(int root,int v){
     48         int x,t=0;
     49         for (x=root;x;val[x]>v?t=x,x=son[x][0]:x=son[x][1]);
     50         if (t) splay(t);
     51         return t?siz[son[t][1]]+1:0;
     52     }
     53     void get(int x){
     54         if (son[x][0]) get(son[x][0]);
     55         que[++cnt]=x;
     56         if (son[x][1]) get(son[x][1]);
     57         son[x][0]=son[x][1]=fa[x]=0;
     58     }
     59 }T;
     60 bool ok;
     61 void read(int &x){
     62     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     63     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     64     if (ok) x=-x;
     65 }
     66 bool cmp(int x,int y){
     67     if (height[x]!=height[y]) return height[x]>height[y];
     68     return x<y;    
     69 }
     70 void get_SA(){
     71     int *x=t1,*y=t2,m=255,tot=0;
     72     for (int i=1;i<=n;i++) sum[x[i]=s[i]]++;
     73     for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
     74     for (int i=n;i>=1;i--) SA[sum[x[i]]--]=i;
     75     for (int len=1;tot<n;len<<=1,m=tot){
     76         tot=0;
     77         for (int i=n-len+1;i<=n;i++) y[++tot]=i;
     78         for (int i=1;i<=n;i++) if (SA[i]>len) y[++tot]=SA[i]-len;
     79         for (int i=1;i<=m;i++) sum[i]=0;
     80         for (int i=1;i<=n;i++) sum[x[y[i]]]++;
     81         for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
     82         for (int i=n;i>=1;i--) SA[sum[x[y[i]]]--]=y[i];
     83         swap(x,y),x[SA[1]]=tot=1;
     84         for (int i=2;i<=n;i++){
     85             if (y[SA[i]]!=y[SA[i-1]]||y[SA[i]+len]!=y[SA[i-1]+len]) tot++;
     86             x[SA[i]]=tot;    
     87         }
     88     }
     89     for (int i=1;i<=n;i++) rank[i]=x[i];
     90 }
     91 void get_height(){
     92     for (int i=1,j=0;i<=n;i++){
     93         if (rank[i]==1) continue;
     94         while (s[i+j]==s[SA[rank[i]-1]+j]) j++;
     95         height[rank[i]]=j;
     96         if (j>0) j--;
     97     }
     98 }
     99 int main(){
    100     read(l),scanf("%s",s+1),n=strlen(s+1);
    101     get_SA(),get_height(),T.init();
    102     for (int i=1;i<=n;i++) root[i]=i;
    103     for (int i=1;i<=n;i++) fa[i]=i;
    104     for (int i=1;i<n;i++) list[i]=i+1;
    105     sort(list+1,list+n,cmp);
    106     for (int i=1;i<n;i++){
    107         int x=find(list[i]-1),y=find(list[i]),lcp=height[list[i]]; cnt=0;
    108         if (T.siz[root[x]]>T.siz[root[y]]) swap(x,y);
    109         int tsiz=T.siz[root[y]];
    110         T.get(root[x]);
    111         for (int j=1,t=que[j];j<=cnt;j++,t=que[j]){
    112             ans+=T.find_next(root[y],SA[t]+l);
    113             ans+=T.find_pre(root[y],lcp+SA[t]+l+1)-tsiz;
    114             ans+=T.find_next(root[y],SA[t]-lcp-l-1);
    115             ans+=T.find_pre(root[y],SA[t]-l)-tsiz;
    116         }
    117         fa[x]=y,T.merge(y);
    118     }
    119     printf("%d
    ",ans);
    120     return 0;
    121 }
  • 相关阅读:
    线程间的通信
    高速排序算法
    LightOJ 1205 Palindromic Numbers
    java异常处理
    Android Bundle类
    Linux守护进程的编程实现
    深入浅出JMS(一)——JMS简单介绍
    Maven安装与配置
    matlab学习------------普通dialog对话框,错误对话框errordlg,警告对话框warndlg
    读书笔记:计算机网络4章:网络层
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4737134.html
Copyright © 2011-2022 走看看