【POJ3415】Common Substrings(后缀数组,单调栈)

题意:

n<=1e5

思路:

我的做法和题解有些不同

题解是维护A的单调栈算B的贡献,反过来再做一次

我是去掉起始位置不同这个限制条件先算总方案数,再把两个串内部不合法的方案数减去

式子展开之后是 sigma(lcp(i,j))-K*L*(L+1)/2+合法(i,j)对数,其中L为连续的height[i]>=K的区域长度

sigma(lcp(i,j))计算部分与BZOJ3238类似

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second 
 19 #define MP make_pair
 20 #define N   210000
 21 #define MOD 1000000007
 22 #define eps 1e-8 
 23 #define pi acos(-1)
 24 #define oo  1000000000
 25 
 26 char a[N],b[N];
 27 int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N],
 28     H[N],stk[N];
 29 ll ans,K,c[N],d[N];
 30 
 31 int read()
 32 { 
 33    int v=0,f=1;
 34    char c=getchar();
 35    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 36    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 37    return v*f;
 38 }
 39 
 40 bool cmp(int *r,int a,int b,int l)
 41 {
 42     return r[a]==r[b]&&r[a+l]==r[b+l];
 43 }
 44 
 45 void getsa(int *r,int *sa,int n,int m)
 46 {
 47     int *x=wa,*y=wb,j,p;
 48     for(i=0;i<n;i++) wc[x[i]=r[i]]++;
 49     for(i=1;i<m;i++) wc[i]+=wc[i-1];
 50     for(i=n-1;i>=0;i--) sa[--wc[x[i]]]=i;
 51     for(j=1,p=1;p<n;j*=2,m=p)
 52     {
 53         p=0;
 54         for(i=n-j;i<n;i++) y[p++]=i;
 55         for(i=0;i<n;i++)
 56          if(sa[i]>=j) y[p++]=sa[i]-j;
 57         for(i=0;i<n;i++) wd[i]=x[y[i]];
 58         for(i=0;i<m;i++) wc[i]=0;
 59         for(i=0;i<n;i++) wc[wd[i]]++; 
 60         for(i=1;i<m;i++) wc[i]+=wc[i-1];
 61         for(i=n-1;i>=0;i--) sa[--wc[wd[i]]]=y[i];
 62         swap(x,y);
 63         p=1; x[sa[0]]=0;
 64         for(i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
 65     }
 66 }    
 67     
 68 void getheight(int *r,int *sa,int n)
 69 {
 70     int i,j,k=0;
 71     for(i=1;i<=n;i++) rank[sa[i]]=i;
 72     for(i=0;i<n;height[rank[i++]]=k)
 73     {
 74         if(k) k--;
 75         j=sa[rank[i]-1];
 76         while(r[i+k]==r[j+k]) k++;
 77     }
 78 }
 79 
 80 void init()
 81 {    
 82         memset(s,0,sizeof(s));
 83         memset(sa,0,sizeof(sa));
 84         memset(wa,0,sizeof(wa));
 85         memset(wb,0,sizeof(wb));
 86         memset(wc,0,sizeof(wc));
 87         memset(wd,0,sizeof(wd));
 88         memset(height,0,sizeof(height));
 89         memset(rank,0,sizeof(rank));
 90 }
 91 
 92 void solve(ll f,int L,int R)
 93 {
 94     //printf("%lld %d %d\n",f,L,R);
 95     for(int i=L-1;i<=R+1;i++) H[i]=height[i];
 96     for(int i=L;i<=R;i++) c[i]=d[i]=0;
 97     stk[1]=L-1; H[L-1]=-oo; 
 98     int top=1;
 99     for(int i=L;i<=R;i++)
100     {
101         while(top&&H[i]<H[stk[top]]) top--;
102         if(stk[top]==L-1) c[i]=L;
103          else c[i]=stk[top]+1;
104         stk[++top]=i;
105     }
106     stk[1]=R+1; H[R+1]=-oo;
107     top=1;
108     for(int i=R;i>=L;i--)
109     {
110         while(top&&H[i]<=H[stk[top]]) top--;
111         if(stk[top]==R+1) d[i]=R;
112          else d[i]=stk[top]-1;
113         stk[++top]=i;
114     } 
115     ll tmp=0;
116     for(int i=L;i<=R;i++) tmp=tmp+(-c[i]+i+1)*(d[i]-i+1)*height[i];
117 //    printf("%lld\n",tmp);
118     ll t=R-L+1;
119     tmp=tmp-K*(t+1)*t/2;
120 //    printf("%lld\n",tmp);
121     for(int i=L;i<=R;i++) tmp=tmp+(-c[i]+i+1)*(d[i]-i+1);
122 //    printf("%lld\n",tmp);
123     ans=ans+f*tmp;
124 } 
125     
126 
127 int main()
128 {
129     freopen("poj3415.in","r",stdin);
130     freopen("poj3415.out","w",stdout); 
131     while(scanf("%lld",&K)!=EOF)
132     {
133         if(K==0) break;
134         ans=0;
135         init();
136         scanf("%s",a);
137         int n1=strlen(a);
138         scanf("%s",b);
139         int n2=strlen(b);
140         for(int i=0;i<n1;i++) 
141          if('A'<=a[i]&&a[i]<='Z') s[i]=a[i]-'A'+2;
142           else s[i]=a[i]-'a'+28;
143         s[n1]=1;
144         n=n1;
145         getsa(s,sa,n+1,100);
146         getheight(s,sa,n);
147     
148         int i=1;
149         while(i<n)
150         {
151             i++;
152             if(height[i]>=K)
153             {
154                 int st=i;
155                 while(i<=n&&height[i]>=K) i++;
156                 if(st<=i-1) solve(-1,st,i-1);
157             }
158         }
159         //printf("%lld\n",ans);
160     
161          
162         init();
163         for(int i=0;i<n2;i++) 
164          if('A'<=b[i]&&b[i]<='Z') s[i]=b[i]-'A'+2;
165           else s[i]=b[i]-'a'+28;
166         s[n2]=1;
167         n=n2;
168         getsa(s,sa,n+1,100);
169         getheight(s,sa,n);
170         i=1;
171         while(i<n)
172         {
173             i++;
174             if(height[i]>=K)
175             {
176                 int st=i;
177                 while(i<=n&&height[i]>=K) i++;
178                 if(st<=i-1) solve(-1,st,i-1);
179             }
180         }
181     //    printf("%lld\n",ans);
182     
183         init();
184         for(int i=0;i<n1;i++) 
185          if('A'<=a[i]&&a[i]<='Z') s[i]=a[i]-'A'+2;
186           else s[i]=a[i]-'a'+28;
187         s[n1]=1;
188         for(int i=0;i<n2;i++)
189          if('A'<=b[i]&&b[i]<='Z') s[n1+i+1]=b[i]-'A'+2;
190           else s[n1+i+1]=b[i]-'a'+28;
191         s[n1+n2+1]=0;
192         n=n1+n2+1;
193         getsa(s,sa,n+1,100);
194         getheight(s,sa,n);
195     //    for(int i=1;i<=n;i++) printf("%d\n",sa[i]);
196         i=1;
197         while(i<n)
198         {
199             i++;
200             if(height[i]>=K)
201             {
202                 int st=i;
203                 while(i<=n&&height[i]>=K) i++;
204                 if(st<=i-1) solve(1,st,i-1);
205             }
206         }
207         //for(int i=0;i<=n1+n2;i++) printf("%d\n",sa[i]);
208         //for(int i=2;i<=n1+n2+2;i++) printf("%d\n",height[i]);
209         printf("%lld\n",ans);
210     } 
211     return 0;
212 }
213      

 

posted on 2018-09-13 20:28  myx12345  阅读(159)  评论(0编辑  收藏  举报

导航