您的位置:首页 > 其它

【GDOI2014 DAY2】Beyond (扩展KMP)

2016-08-20 10:53 369 查看
【题目】

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 2000010

int n;
char s[2][Maxn];
int nt[Maxn],td[2][Maxn];

int c[Maxn];
struct node
{
int x,y;
}t[Maxn];

bool cmp(node x,node y) {return x.y<y.y;}

int mymax(int x,int y) {return x>y?x:y;}

void get_nt(int x)
{
nt[1]=n;
int mx=0,id;
while(s[x][1+mx]==s[x][2+mx]&&mx<=n) mx++;
nt[2]=mx;id=2;
for(int i=3;i<=n;i++)
{
// mx=id+nt[id]-1;
int now=nt[i-id+1];
if(i+now-1<mx) nt[i]=now;//-> i+now<=mx 注意不要写成i+now-1<=mx!!!
else
{
int j=mx-i+1;
if(j<0) j=0;
while(i+j<=n&&s[x][i+j]==s[x][1+j]) j++;
nt[i]=j;
id=i;mx=i+nt[i]-1;
}
}
}

void get_td(int x,int y)
{
int mx=0,id;
while(s[x][1+mx]==s[y][1+mx]) mx++;
td[y][1]=mx;id=1;
for(int i=2;i<=n;i++)
{
int now=nt[i-id+1];
if(i+now-1<mx) td[y][i]=now;
else //i+now-1>=mx
{
int j=mx-i+1;
if(j<0) j=0;
while(i+j<=n&&s[x][1+j]==s[y][i+j]) j++;
td[y][i]=j;
id=i;mx=i+td[y][i]-1;
}
}
}

void add(int x,int y)
{
for(int i=x;i<=n;i+=i&(-i))
c[i]+=y;
}

int get_sum(int x)
{
int ans=0;
for(int i=x;i>=1;i-=i&(-i))
ans+=c[i];
return ans;
}

int ffind(int r)
{
int l=1;
while(l<r)
{
int mid=(l+r)>>1;
if(get_sum(r)-get_sum(mid)>0) l=mid+1;
else r=mid;
}
if(get_sum(l)==0) return 0;
return l;
}

int main()
{
scanf("%d",&n);
scanf("%s%s",s[0]+1,s[1]+1);
get_nt(0);get_td(0,1);

get_nt(1);get_td(1,0);

memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
t[i].x=i;
t[i].y=td[0][i];
add(i,1);
}
sort(t+1,t+1+n,cmp);

int now=1,ans=0;
for(int i=1;i<=n;i++)
{
while(t[now].y<i-1&&now<=n)
{
add(t[now].x,-1);
now++;
}
int x=ffind(td[1][i]+1);
if(x) ans=mymax(ans,x+i-2);
}
printf("%d\n",ans);
return 0;
}


[BEYOND]

2016-08-20 10:55:34
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: