codeforces Moodular Arithmetic 数论


由于gcd(k,p)==1,那么很显然k*x%p = z,这个等式中,x属于(0,p-1),z属于(0,p-1),那么的话,一定是一一对应的
下面给出证明(自己yy的,有错误谢谢指出)
令y = f(kx mod p), x = f(x);
证明当y值确定时,x有唯一值与其对应
y = k*x mod p;
若x不唯一,即x1,x2,有存在n1,n2整数使得
k*x1 - y = n1*p
k*x2 - y = n2*p
相减
k(x1-x2) = (n1-n2)*p;
k*z = n*p
且 z小于p,k小于p,都与p互质
明显k*z = n*p 不成立
同理可证x确定,y不唯一的时候
这样就很简单了,实际就是一个无向图
在同一个联通分块的点,确定其中一个值其他的值就全部被确定
下面给出代码(k = 0,1 需注意)
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
//#define LOCAL
#define maxn 8000005
int vis[maxn];
int cnt = 0;
int part = 0;
int pnt[maxn],head[maxn],nxt[maxn];
void addedge(int u,int v){
	pnt[cnt] = v;
	nxt[cnt] = head[u];
	head[u] = cnt++;
}
void dfs(int u,int f){
	vis[u] = 1;
	for(int i=head[u];~i;i=nxt[i]){
		int v = pnt[i];
		if(v!=f && !vis[v]){
			dfs(v,u);
		}
	}
} 
int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
	MEM(head,-1);
	int p,k;
	cin >> p >> k;
	for(int i=1;i<p;i++){
		int u = i;
		int v = (ll)k*i%p;
		addedge(u,v);
		addedge(v,u);
	}
	for(int i=1;i<p;i++){
		if(!vis[i]){
			part++;
			dfs(i,-1);
		}
	}
	ll sum = 1;
	if(k==0)part = p-1;
	if(k==1)part = p;
	for(int i=1;i<=part;i++){
		sum = (sum*p)%MOD;
	}
	cout << sum << endl;
	return 0;
}









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章