2025/8/27

T1 第一题(1th)

这是一道欧拉函数的题,求在模 \(p\) 意义下 \(x\) 的幂集有多少个不同的值。

转化题意,发现就是算当 \(k\ne 0\) 时, \(x^k\bmod p\) 第一次等于 \(1\)\(k\) 的值。

再次转换,变成求 \(x^k\equiv 1\) \((\bmod p\) \()\) 成立时最小的 \(k\)\(k>0\)),

由于 \(x\bot p\),且 \(x^{\varphi(p)}\equiv 1\) \((\bmod p\) \()\),所以在 \(\varphi(p)\) 的因数里枚举 \(k\),第一个满足同余方程的 \(k\) 就是解。

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int phi(int n){
	if(n==1) return 1;
	int ans=n;
	for(int i=2;i*i<=n;i++){
		if(n%i==0){
			ans=ans/i*(i-1);
			while(n%i==0) n/=i;
		}
	}
	if(n>1) ans=ans/n*(n-1);
	return ans;
}
int ksm(int a,int b,int p){
	int ans=1;
	while(b){
		if(b&1) ans=1ll*ans*a%p;
		a=1ll*a*a%p;
		b>>=1; 
	}
	return ans;
}
int main(){
	int T,p,x;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&p,&x);
		int t=phi(p),ans=t+1;
		for(int i=1;i*i<=t;i++){
			if(t%i) continue;
			int y=ksm(x,i,p);
			if(y==1) ans=min(ans,i);
			y=ksm(x,t/i,p);
			if(y==1) ans=min(ans,t/i);
		}
		printf("%d\n",ans);
	}
	return 0;
}

T2 集合题(set)

根据规则一、规则二可得,集合中的数都可以表示为 \(a^x+kb\) 的形式。

现要判断 \(n\) 是否可以表示为 \(a^x+kb\) 的形式。

枚举 \(x\),判断 \(n-a^x\) 是否为 \(b\) 的倍数。

☆注意:

\(a=1\)\(a^x\) 也会一直为 \(1\)。此时,若 \(n-1\) 不是 \(b\) 的倍数,则会一直循环(因为 \(a^x\) 永远不会超过 \(n\)),所以记得特判~

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int T,n,a,b;
	cin>>T;
	while(T--){
		cin>>n>>a>>b;
		int flag=0;
		long long t=1;
		while(t<=n){
			if((n-t)%b==0){
				flag=1;
				break;
			}
			t*=a;
		}
		if(flag) puts("Yes");
		else puts("No");
	}
	return 0;
} 
posted @ 2025-08-28 11:17  筝小鱼  阅读(35)  评论(4)    收藏  举报