Codeforces Round #334 (603B) Moodular Arithmetic [基础数学]

B. Moodular Arithmetic
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

As behooves any intelligent schoolboy, Kevin Sun is studying psycowlogy, cowculus, and cryptcowgraphy at the Bovinia State University (BGU) under Farmer Ivan. During his Mathematics of Olympiads (MoO) class, Kevin was confronted with a weird functional equation and needs your help. For two fixed integers k and p, where p is an odd prime number, the functional equation states that

for some function . (This equation should hold for any integer x in the range 0 top - 1, inclusive.)

It turns out that f can actually be many different functions. Instead of finding a solution, Kevin wants you to count the number of distinct functions f that satisfy this equation. Since the answer may be very large, you should print your result modulo 109 + 7.

题意:

给出方程f(kx%p)=kf(x)%p ,问在集合A->B上不同的映射函数f 有几种,其中A=B={0,1,2..p-1},p为素数(除了2),k为小于p的一个常数

解法:

如果K=0,F(0)=0 ,其他的映射关系可以随便选择,方案数为p^(p-1)

对于其他的,将x=k*x带入得,f(k*k*x %p)=k*f(kx%p)%p=k*k*f(x)%p

那么 f(x)%p=k*f(x)%p=k*k*f(x)%p=k*k*k*f(x)%p=......

因为(k^m)%p随着m的增大,会变回k,所以是有一个环在其中的。同时根据费马小定理,m肯定是p-1的因子……因为CF很快且单样例,在代码中直接暴力搞了。

每个环的起始位置有p种可能,共(p-1)/m个环,所以方案数为p^((p-1)/m)

对于K=1特判,因为方程为f(x)=f(x),每个数都有p种可能,方案数为P^P

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;


ll p,k,mod=1e9+7;
ll ksm(ll a,ll x){
    ll ans=1;
    while(x){
        if(x&1)ans=(ans*a)%mod;
        x>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
int main(){
    scanff(p);
    scanff(k);
    ll x=1;
    ll m=1;
    rep(i,1,p){
        x=(x*k)%p;
        if(x==1)break;
        m++;
    }
    ll ans=0;
    if(k==0)ans=ksm(p,p-1);
    if(k==1)ans=ksm(p,p);
    if(k>=2)ans=ksm(p,(p-1)/m);
    printf("%lld\n",ans);
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值