牛客NOIP集训三S 牛半仙的妹子数 TJ

题目链接

思路

看了题解才会的,惭愧。
题目中可以发现不变量 \(S = A +B+ C.\)
变换这么多次,一定有一种优化的规律,我们可以往快速幂或者矩阵快速幂上考虑加速。此处矩阵快速幂似乎没戏。
\(A +B \le C\) 时,我们寻找 \(C\) 与不变量 \(S\) 之间的关系,\(C\) 将变换成为 \(C - A - B\) 。记 \(C_1 = C - A - B.\)
可以发现 \(C_1+ S = 2 \times C.\) ,那么 \(C_1= 2 \times C - S.\)
\(A +B > C\) 时,记 \(C_2= 2 \times C.\)
这两个式子看起来关系不大,我们可以通过一些性质来让两个式子相近。
\(A +B \le C\) 时,容易发现 \(2 \times C < 2 \times S\) ,所以 \(C_1\) 可以写作 \(2 \times C \mod S.\)
\(A +B > C\) 时,容易发现 \(2 \times C < S.\) ,所以 \(C_2\) 也可以写作 \(2 \times C \mod S.\)
这样式子变为一致,变换 \(k\) 次,最终得到 \(C \times 2^k \mod S.\)
可以使用快速幂进行优化。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int T;
ll a ,b ,c ,k ,S;
ll power (ll r ,ll b) {
	ll ans = 1;
	while (b) {
		if (b & 1) {
			ans = ans * r % S;
		}
		b >>= 1;
		r = r * r % S;
	}
	return ans % S;
}
int main () {
	scanf ("%d",&T);
	while (T --) {
		scanf ("%lld%lld%lld%lld",&a ,&b ,&c ,&k);
		S = a + b + c;
		printf ("%lld\n",(c * power (2 ,k) % S));
	}
	return 0;
}

posted @ 2020-10-31 17:00  tuscjaf  阅读(55)  评论(0编辑  收藏  举报