http://codeforces.com/contest/635/problem/B
原题很简单。。。。自己傻逼读错题了
题目是 给你一个1到n-1的序列,再给你一个另一个序列
问第2个能否通过前后移动整个序列(看成环状)得到第1个序列
由于相对位置不改变,而且数是唯一的 1到n-1仅出现一次
直接找到 S1[0]==S2【i】,然后从i开始匹配即可。。。。
我以为数字 不是 1到n-1仅出现一次。。。以为是任意的,所以就用hash,
枚举所有的排列情况,然后通过预处理和hash 实现 o1求整个序列的hash值,那么求出所有排列的情况就是o(n)了。。。。
好吧贴hash的代码好了...读错题毁一生
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
#define ull unsigned __int64
int aa[200005],bb[200005];
int cc[200005],dd[200005];
ull pp=239;
ull ret[200005];
ull p[200005];
int n;
void pre(int *cc)
{
int ok=0;
for (int i=n-1;i>=1;i--)
{
ret[ok+1]=ret[ok]*pp+(cc[i]+48);
++ok;
}
}
ull cal(int *cc)
{
ull re=0;
for (int i=n-1;i>=1;i--)
re=re*pp+(cc[i]+48);
return re;
}
int main()
{
cin>>n;
int i,j;
p[1]=1;
for (i=2;i<=200000;i++)
p[i]=p[i-1]*pp;
for (i=1;i<=n;i++)
scanf("%d",&aa[i]);
for (i=1;i<=n;i++)
scanf("%d",&bb[i]);
for (i=1;i<=n;i++)
if (aa[i]==0) break;
int ok1=0;
for (i++;;i++)
{
cc[++ok1]=aa[(i%n==0)?n:(i%n)];
if (ok1==n-1)break;
}
for (i=1;i<=n;i++)
if (bb[i]==0) break;
int ok2=0;
for (i++;;i++)
{
dd[++ok2]=bb[(i%n==0)?n:(i%n)];
if (ok2==n-1)break;
}
pre(dd);
ull has=cal(cc);
int flag=0;
ull ans=ret[n-1];
if (ans==has){flag=1;}
for (i=n-2;i>=1;i--)
{
if ((ret[n-1]-ret[n-i-1]*p[i+1])*p[n-i]+ret[n-i-1]==has)
{flag=1;break;}
}
if (!flag)
printf("NO\n");
else
printf("YES\n");
return 0;
}