cf#8VC Venture Cup 2016 - Final Round (Div. 2 Edition)-B. sland Puzzle 水题/hash

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;
	
}


你可能感兴趣的:(cf#8VC Venture Cup 2016 - Final Round (Div. 2 Edition)-B. sland Puzzle 水题/hash)