gmoj 6844. 【2020.11.02提高组模拟】旅途和生活

6844. 【2020.11.02提高组模拟】旅途和生活

题目大意

给定a,b,n,求(lowbitig(a^n-b^nig))

Solution

证明参考WYD的文章:https://blog.csdn.net/wangyuda123456789/article/details/109458232

对于一奇一偶的情况,(a^n-b^nequiv1(mod 2))恒成立

所以(lowbitig(a^n-b^nig)=1)

对于两个都是奇数的情况,只能暴力去算,但是

即答案一定在64位之内,所以直接unsigned long long自然溢出就好了

对于两个都是偶数的情况

我们可以通过不断除2使a,b转化成一奇一偶的情况或两个奇数的情况

设除了x次,除剩的数为a',b'

则答案为(lowbit(a-b)cdot 2^{xcdot 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
");
            continue;
        }
        if ((a%2)&&(b%2))
        {
            printf("%lld
",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
",tmp);
        }else 
        {
            ans=mo(a,b)*tmp%MO;
            printf("%lld
",ans);
        }
    }
    return 0;
}

如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.
原文地址:https://www.cnblogs.com/Sport-river/p/13929046.html