题解 Wonderful Everyday

传送门

发现所有数都不含 0 但不知道怎么用
发现 \(a, b\) 中肯定有一个跟 \(t\) 的大小差不多但也不知道怎么用

考虑加法只能进一位
所以一种可能是 \(|a|=|t|-1, |b|=|t|-1\)
考虑 999999 + 1 会加出来一些 0
所以若 \(|a|=|t|\),则 \(|b|=|t|-\operatorname{lcp}(a, t)\)\(|b|=|t|-\operatorname{lcp}(a, t)-1\)
于是可以 Z-function + hash 处理,复杂度是 \(O(n)\)
听说这题在 CF 上卡哈希?

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long

int n, m;
int lim;
ll h[N], pw[N], res;
char s[N], t[N];
const ll base=10, mod=114514973;
inline ll hashing(int l, int r) {return ((h[r]-h[l-1]*pw[r-l+1])%mod+mod)%mod;}

namespace force{
	map<ll, int> mp[N];
	vector<pair<ll, int>> buc[N];
	void solve() {
		for (int i=1; i<=n; ++i)
			for (int j=i; j<=n; ++j) {
				ll t=hashing(i, j);
				buc[j].pb({t, i});
				mp[i][t]=j;
			}
		for (int i=1; i<n; ++i) {
			for (auto it:buc[i]) {
				ll t=((res-it.fir)%mod+mod)%mod;
				if (mp[i+1].find(t)!=mp[i+1].end()) {
					cout<<it.sec<<' '<<i<<endl;
					cout<<i+1<<' '<<mp[i+1][t]<<endl;
					exit(0);
				}
			}
		}
	}
}

namespace task{
	int z[N<<1], len;
	char tem[N<<1];
	void z_function() {
		len=n+m+1;
		for (int i=1; i<=m; ++i) tem[i]=t[i]-'0';
		tem[m+1]='$';
		for (int i=1; i<=n; ++i) tem[m+1+i]=s[i];
		for (int i=2,l=1,r=1; i<=len; ++i) {
			if (i<=r && z[i-l+1]<r-i+1) z[i]=z[i-l+1];
			else {
				z[i]=max(0, r-i+1);
				while (i+z[i]<=len && tem[i+z[i]]==tem[1+z[i]]) ++z[i];
			}
			if (i+z[i]-1>r) l=i, r=i+z[i]-1;
		}
		//cout<<"z: "; for (int i=1; i<=len; ++i) cout<<z[i]<<' '; cout<<endl;
	}
	void solve() {
		z_function();
		for (int i=1; i<=n; ++i) {
			if (m>1 && i+(m-1)*2-1<=n && (hashing(i, i+(m-1)-1)+hashing(i+(m-1), i+2*(m-1)-1))%mod==res) {
				cout<<i<<' '<<i+(m-1)-1<<endl;
				cout<<i+(m-1)<<' '<<i+2*(m-1)-1<<endl;
				exit(0);
			}
			int lcp=z[m+1+i], tlen;
			tlen=m-lcp;
			if (tlen && i+m+tlen-1<=n && (hashing(i, i+m-1)+hashing(i+m, i+m+tlen-1))%mod==res) {
				cout<<i<<' '<<i+m-1<<endl;
				cout<<i+m<<' '<<i+m+tlen-1<<endl;
				exit(0);
			}
			if (m>1 && tlen && i>tlen && (hashing(i-tlen, i-1)+hashing(i, i+m-1))%mod==res) {
				cout<<i-tlen<<' '<<i-1<<endl;
				cout<<i<<' '<<i+m-1<<endl;
				exit(0);
			}
			tlen=m-lcp-1;
			if (m>1 && tlen>0 && i+m+tlen-1<=n && (hashing(i, i+m-1)+hashing(i+m, i+m+tlen-1))%mod==res) {
				cout<<i<<' '<<i+m-1<<endl;
				cout<<i+m<<' '<<i+m+tlen-1<<endl;
				exit(0);
			}
			if (m>1 && i>tlen && (hashing(i-tlen, i-1)+hashing(i, i+m-1))%mod==res) {
				cout<<i-tlen<<' '<<i-1<<endl;
				cout<<i<<' '<<i+m-1<<endl;
				exit(0);
			}
		}
	}
}

signed main()
{
	freopen("wonderful.in", "r", stdin);
	freopen("wonderful.out", "w", stdout);

	scanf("%s%s", s+1, t+1);
	n=strlen(s+1); m=strlen(t+1); lim=max(n, m);
	for (int i=1; i<=n; ++i) s[i]-='0';
	for (int i=1; i<=n; ++i) h[i]=(h[i-1]*base+s[i])%mod;
	for (int i=1; i<=m; ++i) res=(res*base+t[i]-'0')%mod;
	pw[0]=1;
	for (int i=1; i<=lim; ++i) pw[i]=pw[i-1]*base%mod;
	//force::solve();
	task::solve();
	
	return 0;
}
posted @ 2022-02-22 17:06  Administrator-09  阅读(2)  评论(0编辑  收藏  举报