今天做题的最大败笔。
分类讨论:
当a是奇数,b是奇数时
由题,答案在unsigned long long范围内,只需考虑最后63位,用自然溢出即可
这30分我TM都想不到
当a,b奇偶性不同时,
a
n
a^n
an 与
b
n
b^n
bn一定不同号,奇数的lowbit必定是1
当a,b都是偶数时,答案转化成a/2,b/2的答案乘上
2
n
2^n
2n
给自己解释一下:
在a,b都是偶数时,
a
n
/
2
n
a^n/2^n
an/2n和
b
n
/
2
n
b^n/2^n
bn/2n必定都是整数
也就是说
a
n
,
b
n
a^n,b^n
an,bn二进制最后n位一定是0
可以将最后n位丢掉(将数向右平移n位),这样的新数,每一位权值相当于原来乘上
2
n
2^n
2n,继续做就可以了
递归处理以上过程就OK
还是没有想到lowbit的本质:最后一个1出现的位置
后面的0可以丢掉的,只要乘上相应的2的幂即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ull unsigned long long
#define ll long long
using namespace std;
const ll mo=1e9+7;
ull mula,mulb;
ll i,j,k,m,n,o,p,l,s,t,a,b;
ll ksm(ll o,ll p)
{
ll ans=1;
for (;p;p>>=1,o=o*o%mo) if (p&1) ans=ans*o%mo;
return ans;
}
ll dg(ll a,ll b)
{
if (!a&&!b) return 0;
if ((a%2)&&(b%2))
{
mula=1,mulb=1;
ull o=a,p=b,q=m;
for (;q;q>>=1,o=o*o) if (q&1) mula*=o;
q=m;
for (;q;q>>=1,p=p*p) if (q&1) mulb*=p;
if (mula<mulb) swap(mula,mulb);
mula-=mulb;
return (mula&(mula^(mula-1)))%mo;
} else if (a%2!=b%2) {
return 1;
} else return dg(a/2,b/2)*ksm(2,m)%mo;
}
int main()
{
freopen("journey.in","r",stdin);
freopen("journey.out","w",stdout);
scanf("%lld",&n);
while (n--)
{
scanf("%lld%lld%lld",&a,&b,&m);
printf("%lld\n",dg(a,b));
}
return 0;
}