https://ac.nowcoder.com/acm/contest/23091/Ahttps://ac.nowcoder.com/acm/contest/23091/A题目:
来自:牛客竞赛
汤姆和杰瑞在一场生日聚会中得到了nnn袋糖果(nnn为偶数),糖果袋中分别有212^121,222^222,…,2n2^n2n颗糖果,出于礼貌,他们无法将这些已分好的糖果进行拆分。现在他们想将糖果袋分成两份(每份有n2\frac{n}{2}2n袋糖果),为了尽量公平,希望两份糖果之间的差值为最小。例如:第一份糖果含aaa颗糖果,第二份含bbb颗糖果,请你们帮助他们使∣a−b∣\left|a - b\right|∣a−b∣的值为最小。
注意:糖果袋中的糖果不能分开,为一个整体。
输入要求:
第一行一个正整数T,代表测试组数。 接下来的T行每行一个整数n。
输出描述:
T行,每行一个整数,代表每组数据所对应的两份糖果的最小差值。 由于输出结果过大,结果对998244353取模。
备注:
1≤T≤10^4 2≤n≤10^6
解题思路:
首先可以想到
假如n袋糖果,则差值最小的分法就是前二分之n-1加上最后一袋和二分之n到n-1袋的差值最小
则从此可以想到用暴力解法,但是显然超时
此时就要对原式进行化简
即得当n袋时,我们需要计算的是2^1+2^2+.......+2^n/2; 即可
但此时运用暴力解法一个个运算必然爆数据类型,是存不下的
所以此时就要运用到快速幂;
快速幂:
假设求2^5;
则将指数部分化为二进制为101;
则原式2^5=2^4*2^1;
举一反三即可得:
代码段:
nt quickpow(long long a,int n)
{
long long res=1;
while(n)
{
if(n%2==1)res=res*a%998244353;
a=a*a%998244353;
n/=2;
}
return res;
}
result即为快速幂的结果;
此时的幂解法比正常的暴力解法快了很多;
则将原式带入快速幂的写法
上代码:
#include<stdio.h>
int quickpow(long long a,int n)
{
long long res=1;
while(n)
{
if(n%2==1)res=res*a%998244353;
a=a*a%998244353;
n/=2;
}
return res;
}
int main()
{
int t,m;
scanf("%d",&t);
while(t--){
scanf("%d",&m);
long long sum=quickpow(2,m/2+1)-2;
printf("%lld\n",sum);
}
return 0;
}