【EXKMP】【2015-2】day1 T3 字符串转换


哈哈这题乱搞骗了个AC~~~~~~





留个字符串hash模板

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
#define ULL unsigned LL
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}

const int base=131;
int n;
char a[1000010],b[1000010];
int next[1000010];
int ansl=1,ansr=-1;
ULL ha[1000010],hb[1000010];
ULL pm[1000010];

ULL hasha(int l,int r)
{
	return ha[r]-ha[l-1]*pm[r-l+1];
}
ULL hashb(int l,int r)
{
	return hb[l]-hb[r+1]*pm[r-l+1];
}
bool check(int l,int r)
{
	int l1=r-l+1,l2=n-r+1,l3=n-l1-l2;
	return hasha(r+1,n) == hashb(l1+1,l1+l2-1) && hasha(1,l-1) == hashb(n-l3,n);
}
void init_hash()
{
	rep(i,1,n) ha[i]=ha[i-1]*base+a[i];
	per(i,n,1) hb[i]=hb[i+1]*base+b[i];
}
void init_next()
{
	int j=0;
	rep(i,2,n)
	{
		while(j&&b[i]!=b[j+1]) j=next[j];
		next[i]=j+=b[i]==b[j+1];
	}
}
void kmp()
{
	int j=0;
	rep(i,1,n)
	{
		while(j&&a[i]!=b[j+1]) j=next[j];
		j+=a[i]==b[j+1];
		int l=i-j+1,r=i;
		if(l>ansl || l==ansl&&r<ansr)
		{
			if(check(l,r))
			{
				ansl=l;
				ansr=r;
			}
		}
	}
}

void input()
{
	gets(a+1); gets(b+1);
    n=strlen(a+1);
}
void solve()
{
	pm[0]=1; rep(i,1,n) pm[i]=pm[i-1]*base;
	init_hash();
	init_next();
	kmp();
	printf("%d %d\n",ansl-2,ansr);
}

int main()
{
    freopen("trans.in","r",stdin); freopen("trans.out","w",stdout);
    input(),solve();
    return 0;
}



放两个EXKMP代码,慢慢看

#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#define PB push_back
#define MP make_pair
#define BG begin()
#define ED end()
#define SZ(x) ((int)((x).size()))
#define FF first
#define SS second
#define foreach(i,x) for (__typeof((x).begin()) i=(x).begin();i!=(x).end();i++)
#define FOR(i,l,r) for (int i=(l);i<=(r);i++)
#define ROF(i,r,l) for (int i=(r);i>=(l);i--)
using namespace std;
#define N 2010000
char _a[N],_b[N];
int g1[N],g2[N];

void cal(string a,int f[]) {
  f[1]=0;
  while (a[f[1]]==a[f[1]+1]) f[1]++;
  int mx=1,n=SZ(a);
  FOR(i,2,n-1) {
    if (f[mx]+mx>i) f[i]=min(f[i-mx],f[mx]+mx-i); else f[i]=0;
    while (a[f[i]]==a[f[i]+i]) f[i]++;
    if (f[i]+i>f[mx]+mx) mx=i;
  };
}

#define fly ""

int main() {
  freopen("trans"fly".in","r",stdin);
  freopen("trans"fly".out","w",stdout);
  gets(_a);
  gets(_b);
  string a(_a),b(_b);
  int n=SZ(a);
  if (SZ(b)!=n) {puts("-1 -1");return 0;};
  string fa(a),fb(b);
  FOR(i,0,n-1) b[i]=_b[n-i-1];
  FOR(i,0,n-1) fa[i]=_a[n-i-1];
  cal(fb+a,g1);
  cal(fa+fb,g2);
  FOR(i,0,n-1) g1[i]=g1[i+n];
  FOR(i,0,n-1) g2[i]=i-g2[2*n-1-i];
  ROF(i,n-2,0) g2[i]=min(g2[i],g2[i+1]);
  int x=-1,y=-1;
  g1[n]=0;
  FOR(i,0,n-2) if (a[i]!=b[i]) break; else {
    int l=n-1-g1[i+1],r=n-1;
    if (g2[l]>i) continue;
    while (l<r) {
      int mid=(l+r+1)>>1;
      if (g2[mid]<=i) l=mid; else r=mid-1;
    };
    if (g2[l]<=i) x=i,y=i+n-l;
  };
  printf("%d %d\n",x,y);
  return 0;
}

#include <map>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#define PB push_back
#define MP make_pair
#define BG begin()
#define ED end()
#define SZ(x) ((int)((x).size()))
#define FF first
#define SS second
#define foreach(i,x) for (__typeof((x).begin()) i=(x).begin();i!=(x).end();i++)
#define FOR(i,l,r) for (int i=(l);i<=(r);i++)
#define ROF(i,r,l) for (int i=(r);i>=(l);i--)
using namespace std;
#define N 2010000
char _a[N],_b[N];
int g1[N],g2[N];

void cal(string a,int f[]) {
  f[1]=0;
  while (a[f[1]]==a[f[1]+1]) f[1]++;
  int mx=1,n=SZ(a);
  FOR(i,2,n-1) {
    if (f[mx]+mx>i) f[i]=min(f[i-mx],f[mx]+mx-i); else f[i]=0;
    while (a[f[i]]==a[f[i]+i]) f[i]++;
    if (f[i]+i>f[mx]+mx) mx=i;
  };
}

#define fly ""

int main() {
  freopen("trans"fly".in","r",stdin);
  freopen("trans"fly".out","w",stdout);
  gets(_a);
  gets(_b);
  string a(_a),b(_b);
  int n=SZ(a);
  if (SZ(b)!=n) {puts("-1 -1");return 0;};
  string fa(a),fb(b);
  FOR(i,0,n-1) b[i]=_b[n-i-1];
  FOR(i,0,n-1) fa[i]=_a[n-i-1];
  cal(fb+a,g1);
  cal(fa+fb,g2);
  FOR(i,0,n-1) g1[i]=g1[i+n];
  FOR(i,0,n-1) g2[i]=i-g2[2*n-1-i];
  ROF(i,n-2,0) g2[i]=min(g2[i],g2[i+1]);
  int x=-1,y=-1;
  g1[n]=0;
  FOR(i,0,n-2) if (a[i]!=b[i]) break; else {
    int l=n-1-g1[i+1],r=n-1;
    if (g2[l]>i) continue;
    while (l<r) {
      int mid=(l+r+1)>>1;
      if (g2[mid]<=i) l=mid; else r=mid-1;
    };
    if (g2[l]<=i) x=i,y=i+n-l;
  };
  printf("%d %d\n",x,y);
  return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值