次芝麻

题目大意:

今有两数\(a,b\),进行\(k\)轮对抗,每轮对抗规则如下:

每次取\(a,b\)中较小者,从较大者中减去其本身的值,并使其值翻倍.

现给出\(a,b,k\),请你求出\(k\)轮对抗后其较小者之值.

solution:

通过打表可以发现,答案具有循环节且长度不超过\(\frac{(n+m)}{2}\),于是暴力枚举跑循环节即可得60分.(燃鹅我只水了50分)

此题十分神奇,满分解法耐人寻味,下面让我们来模拟一轮.

假设有两个数\(n,m\)进行一轮对抗,其中\(n\geq m\),那么可以得出,对抗后得到的两个数为\(2m,n-m\),我们将其放在模\((m+n)\)意义下,可以发现,\(n-m=2n\mod (m+n)\),于是每轮对抗可看作将\(m,n\)分别乘上\(2\)再模\((m+n)\),快速幂求解即可.

code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#define R register
#define next kdjadskfj
#define debug puts("mlg")
#define mod 1004535809
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
inline ll Qpow(ll _,ll __,ll ____){ll ___=1;for(;__;__>>=1){if(__&1) ___*=_,___%=____;_*=_;_%=____;}return ___;}
ll n,m,k;
int main(){	
	freopen("sesame.in","r",stdin);
	freopen("sesame.out","w",stdout);
	n=read();m=read();k=read();
	writeln(min((n*Qpow(2,k,n+m)%(n+m)),(m*Qpow(2,k,n+m)%(n+m))));
}

posted @ 2020-07-31 15:22  月落乌啼算钱  阅读(86)  评论(0编辑  收藏  举报