NOI.AC # 804 [string]

topic

Here Insert Picture Description

Thinking

Note that f is equivalent to the original string applied a permutation p (ie, f (S) pi = Si) , we
p write.
Consider p in the ring (if you do not know what this is, please refer to the subject of the first question Day 4 description), it can be
to find the equivalent transformation is applied once all the letters along this ring "to go" one step further.
Then we can for each ring, will run the letters on the ring times longer after a KMP algorithm to get all
the matching position.
Obviously for a ring is concerned, this position must be a matching arithmetic sequence. The first item is set to t tolerance of d,
the equivalent of the requirements we must answer mod d t.
Next, we need to prove a conclusion, the conclusion can be easily observable by playing table:
Theorem 3.1 all the least common multiple of the loop length does not exceed n.
Because all of the least common multiple loop length does not exceed n, so after so many will turn back, so if
solvable then the answer is not more than n.
So, we can handle the requirements for each of the d remainder md, then md, md + d, md + 2d, · · ·
marked with a mark of d, d finally have all the marks of a figure is the answer.

Code

#include<bits/stdc++.h>
using namespace std;
int n,sz,maxn,ind;
int in[1000005],at[1000005];
char t[1000005],s[1000005];
vector<int> vec[1000005];
bool vis[1000005],ok[1000005];
bool work(int x) {
	for(int i=2;i<n;i++) if(t[vec[in[i]][(at[i]+x)%vec[in[i]].size()]]!=s[i]) return 0;
	return 1;
}
int main() {
	scanf("%d%s%s",&n,s+1,t+1);
	if(s[1]!=t[1]||s[n]!=t[n]) {
		printf("-1\n");
		return 0;
	}
	for(int i=2;i<n;i++)
		if(!vis[i]) {
			sz++;
			vec[sz].push_back(i);
			in[i]=sz;
			vis[i]=1;
			at[i]=0;
			for(int j=i&1?(i+1)/2:i/2+n/2;j!=i;j=j&1?(j+1)/2:j/2+n/2) {
				vec[sz].push_back(j);
				vis[j]=1;
				in[j]=sz;
				at[j]=vec[sz].size()-1;
			}
		}
	for(int i=1;i<=sz;i++)
		if(vec[i].size()>maxn) {
			maxn=vec[i].size();
			ind=i;
		}
	char ch=s[vec[ind][0]];
	for(int i=1;i<=n;i++) if(t[i]==ch) ok[i]=1;
	for(int i=0;i<maxn;i++)
		if(ok[vec[ind][i]])
			if(work(i)) {
				printf("%d\n",i);
				return 0;
			}
	printf("-1\n");
	return 0;
}
Published 703 original articles · won praise 392 · Views 140,000 +

Guess you like

Origin blog.csdn.net/Eric1561759334/article/details/104078250