CF Round334div2 D
题意
给定p和k,p是大于2的素数。找满足f(kx mod p)=k*f(x) mod p的方案数,其中f(1,2,3,4……p-1)->{1,2,3,4……p-1}.
例如p=3,k=2的方案数有三种:
f(0) = 0, f(1) = 1, f(2) = 2.
f(0) = 0, f(1) = 2, f(2) = 1.
f(0) = f(1) = f(2) = 0.
分析
当p=3,k=2的时候:
2*f(0)%3=f(0)=f(2*0%3)
2*f(1)%3=f(2)=f(2*1%3)
2*f(2)%3=f(1)=f(2*2%3)
所以:
0->0
1->2->1
2->1->2
这题主要应用了群的性质,除去0的模p运算,是一个群
先不考虑0,让x和k都非0
我们先证明k * x % p的值各不相同,且会包含全部的1~p-1
假设k * x1 % p = k * x2 % p ,且x1 != x2
在群中,所以每个元素有逆元,那么k^-1 * k * x1 %p = k^-1 * k * x2 %p
所以x1 = x2,由此得证。
利用不停迭代,可以得出下面的关系:
任取x1,有f(x1) = k*f(x2)%p = k^f(k*f(x3)) % p =k^2*f(x2)%p= … = k^l * f(x1)
x1 到 xl就凑成了一个循环的集合,确定x1,则其它元素的值都被确定了,所以对这样一个集合有f(x1)可以为0~p-1的任意值,所以有p种选择,所以找到所有这样的集合个数num,则ans = p ^ num
如何找到集合个数呢,我用的方法是用x1推xl,xl推xl-1,直到循环,xl = k * x1 % p
现在把0加回来,对于k可以特判k=0时,有p^p-1种,k=1时,有p^p种。
当k>1时,对于x=0时,我们固定让f(x) = 1,其它值有上述算法即可。
1 | #include <bits/stdc++.h> |