[TJOI2017]DNA

这道题充分考验了选手的暴力水平。
我们算出(lcp)后一位一位暴力往后移。
甚至算(lcp)的时候都不需要什么非常高级的算法,直接用字符串哈希+二分判断就结束了。
代码:


#include <bits/stdc++.h>
#define il inline
#define gc getchar
const int MAXN = 1e5 + 10;
const int base = 163;
typedef unsigned long long ull;
using namespace std;
ull p[MAXN],h1[MAXN],h2[MAXN];
int n,m,i,j,k,T,ans,l1,l2;
char s1[MAXN],s2[MAXN];
il void print(int x) {
	if(x < 0) putchar('-'),x = -x;if(!x) {putchar('0');return;}
	static int Sta[20];Sta[0] = 0;
	while(x) Sta[++Sta[0]] = x % 10,x /= 10;
	for(int i = Sta[0];i >= 1;i--) putchar(Sta[i] + 48);
	return;
}
il ull get1(int l,int r) {
	return h1[r] - p[r - l + 1] * h1[l - 1];
}
il ull get2(int l,int r) {
	return h2[r] - p[r - l + 1] * h2[l - 1];
}
il int lcp(int S1,int S2,int len) {
	int l = 1,r = len,res = 0;
	while(l <= r) {
		int mid = l + r >> 1;
		if(get1(S1,S1 + mid - 1) == get2(S2,S2 + mid - 1)) {
			res = mid;l = mid + 1;
		} else r = mid - 1;
		//cout << l << ' ' << r << endl;
	}
	return res;
}
il bool judge(int x) {
	bool res = 0;int y = 1,len = x + l2 - 1,dbg = x;
	for(int i = 1;i <= 3;i++) {
		int tmp = lcp(x,y,l2 - y + 1);
		x += tmp + 1;y += tmp + 1;
		if(y > l2) return 1;
	} 
	return get1(x,len) == get2(y,l2);
}
int main() {
	scanf("%d",&T);
	while(T--) {
		scanf("%s",s1 + 1);
		scanf("%s",s2 + 1);
		l1 = strlen(s1 + 1),l2 = strlen(s2 + 1),ans = 0;   
		p[0]  = 1;for(int i = 1;i <= l1;i++) p[i] = p[i - 1] * base;
		h1[0] = 0;for(int i = 1;i <= l1;i++) h1[i] = h1[i - 1] * base + (s1[i] - 48);
		h2[0] = 0;for(int i = 1;i <= l2;i++) h2[i] = h2[i - 1] * base + (s2[i] - 48);
		for(int i = 1;i + l2 - 1 <= l1;i++) {
			if(judge(i)) ans++;   
		}
	//	lcp(2,2,4);
		print(ans);puts("");
	}	
}
原文地址:https://www.cnblogs.com/Sai0511/p/10410217.html