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

11 篇文章 0 订阅

今天做题的最大败笔。
分类讨论:
当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 anbn二进制最后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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值