2019山东省赛K - Happy Equation ZOJ - 4123 题解

题意:

  一个数论题,要求满足如下等式的x有多少个。

    

思路:

  当时比赛是,队伍看到这个题,也没有做太多的思考,就是无从下手,几乎放弃。但是看到学校另外两支队伍都过了这个题,感觉自己还是好菜。

  打表可以发现,当a为奇数的时候答案为1。当a为偶数的时候,x一定也是偶数,这个还是比较明显的。

  对左边进行推导,因为a为偶数,设a=2*t,所以a^x=2^x*t^x,所以当x大于p时,这个求余之后一定为0。由于p很小,可以直接暴力求解,所以对于右边直接考虑x^a求余之后为0的x的情况。由于x为偶数。我们再次对x分解,设x=2^k*t,就是把x写成一个2的 次幂和t的乘积的形式,所以x^a=2^(ka)*t^a,所以只需要ka>=p,就可以满足条件,而且只有ka>=p可以满足条件,因为t^a不可能可以整除,所以现在要求k>=p/a,对p/a取上整即可,就是考察有多少个t,在1-up的范围内(up为x的上界),个数为up/ceil(p/a)/2^k。当然最后的答案要减去1-p范围内的数,因为这一部分是特殊考虑的。

代码:

 1 #include <iostream>
 2 #include<cmath>
 3 #include<stdio.h>
 4 //a^x 与x^a
 5 // 1<=x<=2^p
 6 using namespace std;
 7 #define ll long long
 8 ll ppow(int x,int n,ll mod)
 9 {
10     ll res=1;
11     ll base=x;
12     while(n)
13     {
14         if(n&1)
15             res=(res*base)%mod;
16         base=(base*base)%mod;
17         n>>=1;
18     }
19     return res%mod;
20 }
21 int main()
22 {
23     int a,p;
24     int T;
25     while(~scanf("%d",&T))
26     {
27         while(T--)
28         {
29             scanf("%d%d",&a,&p);
30 
31             if(a%2)
32             {
33                 cout<<1<<endl;
34                 continue;
35             }
36             //x>=p
37             ll  up=(1LL<<p);
38             ll ans=0;
39             for(int i=1;i<=p;i++){
40                 if(ppow(a,i,up)==ppow(i,a,up))ans++;
41             }
42             ll tem=ceil(p/(a+0.0));
43             ans+=(up>>tem)-(p>>tem);
44             cout<<ans<<endl;
45         }
46     }
47 
48     return 0;
49 }

 

转载于:https://www.cnblogs.com/gzr2018/p/10883184.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值