zoukankan      html  css  js  c++  java
  • 【luogu U137469】分肉(结论)

    分肉

    题目链接:luogu U137469

    题目大意

    给你两个数 n,m 然后问你对它进行 k 次变化后,小的数是多少。
    定义一次变换为让大的数减去小的数,然后让小的数乘二。

    思路

    这道题是结论题。

    首先发现 (n+m) 为定值。

    你考虑进行变换,假设大的一直是大的,小的一直是小的。

    (n,m(n>m))
    (n-m,2m)
    (n-3m,4m)
    (n-7m,8m)

    发现右边每次乘二((2^x)),左边好像没有什么特别的规律,好像就是右边的减 (m) 的系数会表示乘 (2^x-1)
    那你发现一个是 (2^x),一个是 (2^x-1),而且如果把左边的表示乘 ((n+m)-8m),那就是 (2^x) 了。

    那它一个 (2^xm),一个是 ((n+m)-2^xm), 你考虑去掉 ((n+m)),那要怎么去掉呢?

    因为它是定值,我们考虑取模,那这一模 ((n+m)),左边是 (2^xm),右边就是 (-2^xmequiv 2^x(n+m)-2^xmequiv 2^xnmod(n+m))

    然后你发现其实就是两个数在(mod(n+m)) 的情况下乘 (2^k) 的结果。
    然后就可以啦。

    代码

    #include<cstdio>
    #include<iostream>
    #define ll long long
    
    using namespace std;
    
    int T;
    ll n, m, k;
    
    ll ksm(ll x, ll y) {
    	ll re = 1;
    	while (y) {
    		if (y & 1) re = re * x % (n + m);
    		x = x * x % (n + m);
    		y >>= 1;
    	}
    	return re;
    }
    
    int main() {
    	scanf("%d", &T);
    	while (T--) {
    		scanf("%lld %lld %lld", &n, &m, &k);
    		ll x = n * ksm(2, k) % (n + m);//求出 n 的最终大小(拿 n+m 减去就是 m 的了)
    		printf("%lld
    ", min(x, n + m - x));//输出最小值
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    P3254 圆桌问题
    P4868 Preprefix sum
    2021sd省选游记
    P4145 上帝造题的七分钟2 / 花神游历各国
    P2801 教主的魔法
    P4147 玉蟾宫(悬线法)
    P1944 最长括号匹配
    CF1214D Treasure Island
    Loadrunner与kylinPET的能力对比测试--web动态请求
    Summer——从头开始写一个简易的Spring框架
  • 原文地址:https://www.cnblogs.com/Sakura-TJH/p/luogu_U137469.html
Copyright © 2011-2022 走看看