gmoj 6844. 【2020.11.02提高组模拟】旅途和生活
6844. 【2020.11.02提高组模拟】旅途和生活
题目大意
给定a,b,n,求\(lowbit\big(a^n-b^n\big)\)
Solution
证明参考WYD的文章:https://blog.csdn.net/wangyuda123456789/article/details/109458232
对于一奇一偶的情况,\(a^n-b^n\equiv1(mod\ 2)\)恒成立
所以\(lowbit\big(a^n-b^n\big)=1\)
对于两个都是奇数的情况,只能暴力去算,但是
即答案一定在64位之内,所以直接unsigned long long自然溢出就好了
对于两个都是偶数的情况
我们可以通过不断除2使a,b转化成一奇一偶的情况或两个奇数的情况
设除了x次,除剩的数为a',b'
则答案为\(lowbit(a-b)\cdot 2^{x\cdot n}\)
#include <cstdio>
#include <algorithm>
#define MO 1000000007
#define ll unsigned long long
#define LL long long
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int t,n,a,b,x;
ll sum;
LL ans,tmp;
ll ksm(ll x,int y)
{
ll sum=1;
while (y)
{
if (y&1) sum=sum*x;
x=x*x;
y>>=1;
}
return sum;
}
LL ks(LL x,int y)
{
LL sum=1;
while (y)
{
if (y&1) sum=sum*x%MO;
x=x*x%MO;
y>>=1;
}
return sum;
}
LL mo(int a,int b)
{
ll sum=ksm(a,n)-ksm(b,n);
return (sum&(sum^(sum-1)))%MO;
}
int main()
{
open("journey");
scanf("%d",&t);
for (;t;t--)
{
scanf("%d%d%d",&a,&b,&n);
x=0;
if (((a%2)&&(b%2==0))||((a%2==0)&&(b%2)))
{
printf("1\n");
continue;
}
if ((a%2)&&(b%2))
{
printf("%lld\n",mo(a,b));
continue;
}
while ((a%2==0) && (b%2==0))
{
a/=2;b/=2;x++;
}
tmp=ks(2,n*x);
if (a%2==0 || b%2==0)
{
printf("%lld\n",tmp);
}else
{
ans=mo(a,b)*tmp%MO;
printf("%lld\n",ans);
}
}
return 0;
}
如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.