hdu 6189 Law of Commutation

本文探讨了一种高效解决特定数学问题的方法,通过快速模幂和条件判断优化,实现对特定条件下的数量计数。适用于快速解决模运算相关的问题,尤其在数论和算法竞赛中具有应用价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

给定n,a, 在区间[1,2^n]求满足a^b %m =b^a %m的b的个数

直接用快速模幂从1遍历到2^n,会TL;
判断a为奇数时,答案为1,为偶数时b也偶数,遍历减去一半,还是会TL;还需要继续剪枝T…T

(1) a为奇数:
    ans=1;
(2) a为偶数:
  因为    m=2^n,m为偶数
  所以    a^b %m 结果也为偶数
  又因为  a^b %m = b^a % m
  所以    b^a %m 结果也为偶数,b也为偶数
  a为偶数           
    令a=2 * x   =>  a^b=2^b * x^b       
  i, 当b<n时直接暴力 
  ii,当b>=n时,
     (2^b * x^b) % 2^n =0  (因子取模为零)
     此时b^a % 2^n 也要为零    
     b为偶数
       令b=(2^x) * y  =>  b^a=2^(ax) * y^a
       即当 ax>=n时满足条件
         x>=n/a,b=2^x * y;
       对x限制后,只要满足x条件,无论y怎样,都可以取x=n/a,计算y个数即可
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll; 

ll power(ll a,ll b){ //快速幂 
	ll result=1;
	for(;b;b>>=1){
		if(b&1){
			result*=a;
		}
		a*=a;
	}
	return result;
}

ll quic_power(ll a,ll b,ll mod){ //快速模幂 
	ll result=1;
	for(;b;b>>=1){
		if(b&1){
			result*=a;
			result%=mod;
		}
		a*=a;
		a%=mod;
	}
	return result;
}


int main(){
	int n,a,cnt;
	while(~scanf("%d%d",&n,&a)){
		int ans=0;
		if(a&1)  //若a为奇数 
			ans=1;
		else{
			ll mod=power(2,n);  //模  b [1,m] 
		
			cnt=0;
			for(int i=2;i<=n;i+=2)  //n以内满足条件的偶数b 
				if(quic_power(a,i,mod)==quic_power(i,a,mod))
					cnt++;
			
			ll x=n/a;  //当b>n时 
			if(x*a<n)
				x++;
			ll b=power(2,x);
			
			cnt+=(mod/b-n/b); //加上b>n之后满足条件的个数 
			ans=cnt;
		} 
		printf("%d\n",ans);	
	}
	return 0;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值