我是靠谱客的博主 怕黑香菇,这篇文章主要介绍uva12387 - Alphabet Soup链接题解代码,现在分享给大家,希望可以做个参考。

链接

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3809

题解

要让旋转之后重合,确定下第一个点转到哪里之后,剩下的只需要相对次序不变就好,那么我就把这个序列先复制一遍放在末尾,然后差分,对原序列也差分,做一个匹配就好了,我用的是kmp
计数的任务交给polya定理

代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//polya定理、kmp #include <bits/stdc++.h> #define mod 100000007ll #define maxn 1000010 #define cl(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; ll fastpow(ll a, ll b) { ll t=a, ans=1; for(;b;b>>=1,t=t*t%mod)if(b&1)ans=ans*t%mod; return ans; } ll gcd(ll a, ll b){return !b?a:gcd(b,a%b);} ll read(ll x=0) { ll c, f=1; for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f; for(;isdigit(c);c=getchar())x=x*10+c-48; return f*x; } ll nex[maxn], a[maxn], S, P, t[maxn]; void init() { ll i, j; cl(nex), cl(a), cl(t); for(i=1;i<=P;i++)a[i]=read(); sort(a+1,a+P+1); for(i=1;i<=P;i++)a[P+i]=a[i]+360000; for(i=P*2;i;i--)a[i]-=a[i-1]; for(i=2;i<=P;i++)t[i-1]=a[i]; for(i=2,j=0;i<P;i++) { for(;t[j+1]!=t[i] and j;j=nex[j]); nex[i]=t[j+1]==t[i]?++j:0; } } void work() { ll i, j, ans=0, cnt=0; if(P==1) { printf("%lldn",S); return; } for(i=2,j=0;i<P*2;i++) { for(;t[j+1]!=a[i] and j;j=nex[j]); if(t[j+1]==a[i])j++; if(j==P-1) { ans=(ans+fastpow(S,gcd(P,i-P)))%mod; // printf("route %lld, ans=%lldn",i-P,ans); cnt++; j=nex[j]; } } ans=ans*fastpow(cnt,mod-2)%mod; printf("%lldn",ans); } int main() { while(S=read(),P=read(),S>0) { init(); work(); } return 0; }

最后

以上就是怕黑香菇最近收集整理的关于uva12387 - Alphabet Soup链接题解代码的全部内容,更多相关uva12387内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部