zoukankan      html  css  js  c++  java
  • 字符串[未AC](后缀自动机):HEOI 2016 str

      超级恶心,先后用set维护right,再用主席树维护,全部超时,本地测是AC的。放心,BZOJ上还是1S限制,貌似只有常数优化到一定境界的人才能AC吧。

      总之我是精神胜利了哦耶QAQ

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #define lb lower_bound
     5 #define ub upper_bound
     6 #include <set>
     7 using namespace std;
     8 const int N=200010;
     9 int fa[N][20],ch[N][2],len[N],pos[N];
    10 int lst,cnt;set<int>t[N];
    11 int n,Q,a,b,c,d;char s[N];
    12 void Init(){lst=cnt=1;}
    13 void Insert(int c){
    14     int p=lst,np=lst=++cnt;len[np]=len[p]+1;
    15     while(p&&ch[p][c]==0)ch[p][c]=np,p=fa[p][0];
    16     if(!p)fa[np][0]=1;
    17     else{
    18         int q=ch[p][c],nq;
    19         if(len[q]==len[p]+1)fa[np][0]=q;
    20         else{
    21             len[nq=++cnt]=len[p]+1;
    22             fa[nq][0]=fa[q][0];fa[q][0]=fa[np][0]=nq;
    23             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    24             while(ch[p][c]==q)ch[p][c]=nq,p=fa[p][0];
    25         }
    26     }
    27 }
    28 int cntE,fir[N],to[N],nxt[N];
    29 void addedge(int a,int b){
    30     nxt[++cntE]=fir[a];
    31     to[fir[a]=cntE]=b;
    32 }
    33  
    34 set<int>Merge(set<int>x,set<int>y){
    35     if(x.size()<y.size())swap(x,y);
    36     x.insert(y.begin(),y.end());
    37     //delete &y;
    38     return x;
    39 }
    40  
    41 void DFS(int x){
    42     for(int i=fir[x];i;i=nxt[i])
    43         DFS(to[i]),t[x]=Merge(t[x],t[to[i]]);
    44 }
    45  
    46 bool Judge(int p,int l,int r){
    47     return t[p].lb(l)!=t[p].ub(r);
    48 }
    49 
    50 int Find(int x,int l){
    51     for(int i=17;i>=0;i--)
    52         if(fa[x][i]&&len[fa[x][i]]>=l)
    53             x=fa[x][i];
    54     return x;        
    55 }
    56 
    57 int Solve(){
    58     int l=0,r=min(d-c,b-a)+1;
    59     while(l<=r){
    60         int mid=(l+r)>>1;
    61         int p=Find(pos[c],mid);
    62         if(Judge(p,a,b-mid+1))l=mid+1;
    63         else r=mid-1;
    64     }
    65     return r;
    66 }
    67 
    68 
    69 int main(){
    70     freopen("heoi2016_str5.in","r",stdin);
    71     freopen("heoi2016_str.out","w",stdout);
    72     Init();scanf("%d%d%s",&n,&Q,s+1);
    73     for(int i=n;i>=1;i--){Insert(s[i]-'a');t[pos[i]=lst].insert(i);}
    74     for(int i=2;i<=cnt;i++)addedge(fa[i][0],i);DFS(1);
    75     for(int k=1;k<=17;k++)
    76         for(int i=1;i<=cnt;i++)
    77             fa[i][k]=fa[fa[i][k-1]][k-1];
    78     while(Q --){
    79         scanf("%d%d%d%d",&a,&b,&c,&d);
    80         printf("%d
    ",Solve());
    81     }
    82     return 0;
    83 }

      然后是应该AC的:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <ctime>
     5 using namespace std;
     6 const int N=200010;
     7 int fa[N][20],ch[N][26],len[N],pos[N];
     8 int lst,cnt,n,Q;char s[N];
     9 void Init(){lst=cnt=1;}
    10 void Insert(int c){
    11     int p=lst,np=lst=++cnt;len[np]=len[p]+1;
    12     while(p&&ch[p][c]==0)ch[p][c]=np,p=fa[p][0];
    13     if(!p)fa[np][0]=1;
    14     else{
    15         int q=ch[p][c],nq;
    16         if(len[q]==len[p]+1)fa[np][0]=q;
    17         else{
    18             len[nq=++cnt]=len[p]+1;
    19             fa[nq][0]=fa[q][0];fa[q][0]=fa[np][0]=nq;
    20             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    21             while(ch[p][c]==q)ch[p][c]=nq,p=fa[p][0];
    22         }
    23     }
    24 }
    25 int cntE,fir[N],to[N],nxt[N];
    26 void addedge(int a,int b){
    27     nxt[++cntE]=fir[a];
    28     to[fir[a]=cntE]=b;
    29 }
    30  
    31 int id[N],ed[N],tot;
    32 int rt[N],sum[N*25],son[N*25][2];
    33 void Insert(int pre,int &rt,int l,int r,int g){
    34     sum[rt=++tot]=sum[pre]+1;
    35     son[rt][0]=son[pre][0];
    36     son[rt][1]=son[pre][1];
    37     if(l==r)return;int mid=l+r>>1;
    38     if(mid>=g)Insert(son[pre][0],son[rt][0],l,mid,g);
    39     else Insert(son[pre][1],son[rt][1],mid+1,r,g);
    40 }
    41 int Query(int x,int l,int r,int a,int b){
    42     if(l>=a&&r<=b||!sum[x])return sum[x];
    43     int ret=0,mid=l+r>>1;
    44     if(mid>=a)ret=Query(son[x][0],l,mid,a,b);
    45     if(mid<b)ret+=Query(son[x][1],mid+1,r,a,b);
    46     return ret;
    47 }
    48  
    49 bool Judge(int p,int l,int r){
    50     int A=Query(rt[l-1],1,cnt,id[p],ed[p]);
    51     int B=Query(rt[r],1,cnt,id[p],ed[p]);
    52     return A<B;
    53 }
    54 
    55 int st[N],top;
    56 int main(){
    57     freopen("heoi2016_str.in","r",stdin);
    58     freopen("heoi2016_str.out","w",stdout);
    59     Init();scanf("%d%d%s",&n,&Q,s+1);
    60     for(int i=n;i>=1;i--)Insert(s[i]-'a'),pos[i]=lst;
    61     for(int i=2;i<=cnt;i++)addedge(fa[i][0],i);
    62     for(int k=1;k<=18;k++)for(int i=1;i<=cnt;i++)
    63         fa[i][k]=fa[fa[i][k-1]][k-1];
    64     st[top=1]=1;
    65     while(top){
    66         int x=st[top];
    67         if(id[x]){ed[x]=tot;top--;}
    68         else{
    69             id[x]=++tot;
    70             for(int i=fir[x];i;i=nxt[i])
    71                 st[++top]=to[i];
    72         }
    73     }
    74     
    75     tot=0;
    76     for(int i=1;i<=n;i++)
    77         Insert(rt[i-1],rt[i],1,cnt,id[pos[i]]);    
    78     int a,b,c,d;    
    79     while(Q --){
    80         scanf("%d%d%d%d",&a,&b,&c,&d);
    81         int l=0,r=min(d-c,b-a)+1;
    82         while(l<=r){
    83             int mid=l+r>>1,p=pos[c];
    84             for(int i=18;i>=0;i--)
    85                 if(fa[p][i]&&len[fa[p][i]]>=mid)
    86                     p=fa[p][i];
    87             if(Judge(p,a,b-mid+1))l=mid+1;
    88             else r=mid-1;
    89         }
    90         printf("%d
    ",r);
    91     }
    92     //printf("%lf
    ", (double)clock()/CLOCKS_PER_SEC);
    93     return 0;
    94 }

       有毒啊,后缀数组都写挂了,TLE。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 const int N=100010;
      6 int n,Q,r[N],Wa[N],Wb[N],Wv[N],Ws[N];
      7 int rk[N],sa[N],lcp[N],mm[N],Min[N][20];
      8 int len,cnt,ch[N*20][2],sum[N*20],rt[N];
      9 char s[N];
     10 bool cmp(int *p,int i,int j,int l){
     11     return p[i]==p[j]&&p[i+l]==p[j+l];
     12 }
     13 
     14 void DA(int n,int m){
     15     int i,j,p,*x=Wa,*y=Wb;
     16     for(i=0;i<m;i++)Ws[i]=0;
     17     for(i=0;i<n;i++)++Ws[x[i]=r[i]];
     18     for(i=1;i<m;i++)Ws[i]+=Ws[i-1];
     19     for(i=n-1;i>=0;i--)sa[--Ws[x[i]]]=i;
     20     
     21     for(p=1,j=1;p<n;m=p,j<<=1){
     22         for(p=0,i=n-j;i<n;i++)y[p++]=i;
     23         for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
     24         for(i=0;i<m;i++)Ws[i]=0;
     25         for(i=0;i<n;i++)++Ws[Wv[i]=x[y[i]]];
     26         for(i=1;i<m;i++)Ws[i]+=Ws[i-1];
     27         for(i=n-1;i>=0;i--)sa[--Ws[Wv[i]]]=y[i];
     28         for(swap(x,y),x[sa[0]]=0,i=1,p=1;i<n;i++)
     29             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
     30     }
     31 }
     32 
     33 void LCP(int n){
     34     int i,j,k=0;
     35     for(i=1;i<=n;i++)rk[sa[i]]=i;
     36     for(i=0;i<n;lcp[rk[i++]]=k)
     37         for(k-=k>0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
     38 }
     39 
     40 #define mid ((l+r)>>1)
     41 void Insert(int pre,int &rt,int l,int r,int g,int d){
     42     sum[rt=++cnt]=sum[pre]+d;ch[rt][0]=ch[pre][0];
     43     ch[rt][1]=ch[pre][1];if(l==r)return;
     44     if(mid>=g)Insert(ch[pre][0],ch[rt][0],l,mid,g,d);
     45     else Insert(ch[pre][1],ch[rt][1],mid+1,r,g,d);
     46 }
     47 
     48 int Query(int pre,int rt,int l,int r,int a,int b){
     49     if(l>=a&&r<=b)return sum[rt]-sum[pre];int ret=0;
     50     if(mid>=a)ret=Query(ch[pre][0],ch[rt][0],l,mid,a,b);
     51     if(mid<b)ret+=Query(ch[pre][1],ch[rt][1],mid+1,r,a,b);
     52     return ret;
     53 }
     54 
     55 void Prepare(int n){
     56     mm[0]=-1;
     57     for(int i=1;i<=n;i++){
     58         mm[i]=mm[i-1];
     59         if(!(i&i-1))mm[i]+=1;
     60         Min[i][0]=lcp[i];
     61     }
     62     for(int k=1;k<=mm[n];k++)
     63         for(int i=1;i+(1<<k-1)<=n;i++)
     64             Min[i][k]=min(Min[i][k-1],Min[i+(1<<k-1)][k-1]);
     65 }
     66 
     67 int Qmin(int x,int y){
     68     if(x>y)swap(x,y);x+=1;int l=mm[y-x+1];
     69     return min(Min[x][l],Min[y-(1<<l)+1][l]);
     70 }
     71 
     72 int a,b,c,d,lo,hi;
     73 bool Check(int x,int n){
     74     int l=1,r=rk[c-1]-1,pl,pr;
     75     while(l<=r){
     76         if(Qmin(mid,rk[c-1])>=x)r=mid-1;
     77         else l=mid+1;    
     78     }pl=l;
     79     l=rk[c-1]+1,r=n;
     80     while(l<=r){
     81         if(Qmin(rk[c-1],mid)>=x)l=mid+1;
     82         else r=mid-1;
     83     }pr=r;
     84     return Query(rt[pl-1],rt[pr],1,n,a,b-x+1);
     85 }
     86 
     87 int main(){
     88     freopen("heoi2016_str.in","r",stdin);
     89     freopen("heoi2016_str.out","w",stdout);
     90     scanf("%d%d%s",&n,&Q,s);
     91     for(;s[len];len++)r[len]=s[len];
     92     DA(len+1,128);LCP(len);Prepare(len);
     93     for(int i=1;i<=len;i++)
     94         Insert(rt[i-1],rt[i],1,len,sa[i]+1,1);
     95     while(Q--){
     96         scanf("%d%d%d%d",&a,&b,&c,&d);
     97         lo=1,hi=min(b-a+1,d-c+1);
     98         while(lo<=hi){
     99             int MID=(lo+hi)>>1;
    100             if(Check(MID,len))lo=MID+1;
    101             else hi=MID-1;
    102         }
    103         printf("%d
    ",hi);
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    poj 3253 Fence Repair (优先队列,哈弗曼)
    容斥原理 (转载)
    poj 1088 滑雪 DP(dfs的记忆化搜索)
    饭卡 01背包 + 贪心
    N分之一 竖式除法模拟
    poj2325 大数除法+贪心
    优先队列重载运算符< 以及初始化列表
    POJ 2718 Smallest Difference(贪心 or next_permutation暴力枚举)
    HASH算法
    字符串匹配算法——KMP算法
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5793102.html
Copyright © 2011-2022 走看看