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;
}









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