PLQ和他的小伙伴们 Beta Round #9 (酱油杯noi考后欢乐赛)
(每个测试点1s)
背景
这一天,PLQ和他的小伙伴们在大街上走着,突然他们看见了一件令人惊讶的事情,他们决定要惊呆。初始情况下他们的惊呆指数均为0。
描述
已知PLQ和他的小伙伴们一共有n名,编号从1到n,顺时针排成一个环,如图所示。
他们决定以报数的形式来惊呆,一开始让编号为a的人开始报数,他报1,之后顺时针报下去。报到X1的人惊呆指数加1;然后下一个人再从1开始报数,报到X2的人惊呆指数加1,;如此m轮之后,每个人的惊呆指数都能确定。回来之后,他准备来考考你这个神犇,他只告诉你X1~Xm和每个人的最终惊呆指数,要你快速求出a来。
输入格式
输入有3行,第一行有两个用空格隔开的正整数n和m,第二行有m个用空格隔开的正整数,第i个为Xi,第三行有n个用空格隔开的正整数,第j个为Yj,表示编号为j的人的最终惊呆指数为Yj。
输出格式
输出有一行或两行,若能算出唯一的a则只输出一行,这一行只有一个正整数a。如果不能确定(即有多个可能),请输出“Cannot determine!”(不含引号),并在第二行输出可能的方案数。
样例输入1
5 6 2 2 3 4 5 1 0 2 3 0 1
样例输出1
2
样例输入2
4 6 1 3 2 1 3 2 2 1 2 1
样例输出2
Cannot determine! 2
数据范围与约定
- 100%的数据,0<n≤1000000,0<m≤2000000,0<Xi≤1000000000,0≤Yj≤m。
这个题是个环,我们会发现,实际上从哪个点开始是不重要的,因为最终的答案都是一样的,只是顺序不同而已,那么我们直接以1为起点,然后把结果复制一遍接在后面,
然后kmp即可。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 2000000+5 14 #define maxm 10000+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int n,m,cnt=-1,tot,ans,a[maxn],b[maxn],next[maxn]; 30 int main(){ 31 //freopen("input.txt","r",stdin); 32 //freopen("output.txt","w",stdout); 33 n=read();m=read(); 34 for1(i,m){ 35 cnt+=read();cnt%=n; 36 a[cnt+1]++; 37 } 38 for1(i,n)a[n+i]=a[i]; 39 for1(i,n)b[i]=read(); 40 for(int i=2,j=0;i<=n;i++){ 41 while(j&&b[j+1]!=b[i])j=next[j]; 42 if(b[j+1]==b[i])j++; 43 next[i]=j; 44 } 45 for(int i=1,j=0;i<=2*n-1;i++){ 46 while(j&&b[j+1]!=a[i])j=next[j]; 47 if(b[j+1]==a[i])j++; 48 if(j==n){ 49 tot++; 50 ans=2*n-i+1; 51 j=next[j]; 52 } 53 } 54 if(tot!=1)printf("Cannot determine!\n%d\n",tot); 55 else printf("%d\n",(ans-1)%n+1); 56 return 0; 57 }