今天去做了几道签到题,发现自己的幕乘居然有问题
我的幕乘板子:
#include<cstdio>
#include<cstdlib>
#include<iostream>
typedef unsigned long long llong;
using namespace std;
llong mod_pow(llong x,llong n,llong mod)
{
llong a = llong x;
llong res = 1;
while(n>0)
{
if(n&1) res = res*a%mod;
a = a*a%mod;
n>>=1;
}
return res;
}
int main()
{
int test;
llong m,n;
scanf("%d",&test);
while(test--)
{
cin>>m>>n;
llong ans = mod_pow(m,n,9999999967);
cout<<ans<<endl;
}
}
这道题和以前的不同,mod 太大了,快有1e11了,用上面的代码会发现2的63以上都是0,然后发现是因为(a * a)%mod的问题,因为mod比较大所以a * a结果可能会溢出,结束的时候看见别人用的__int 128来存放a,这样a * a 就不会溢出因为还要mod9999999967。
下面是改进代码:
#include<cstdio>
#include<cstdlib>
#include<iostream>
typedef unsigned long long llong;
using namespace std;
llong mod_pow(llong x,llong n,llong mod)
{
__int128 a = (__int128) x;
llong res = 1;
while(n>0)
{
if(n&1) res = res*a%mod;
a = a*a%mod;
n>>=1;
}
return res;
}
int main()
{
int test;
llong m,n;
scanf("%d",&test);
while(test--)
{
cin>>m>>n;
llong ans = mod_pow(m,n,9999999967);
cout<<ans<<endl;
}
}
题目描述
20级的学弟学妹们来了,实验室里可怜弱小又无助的wzc学弟终于变成了学长,可以压迫下一级了(?)。
但是wzc学长苦于自己的实力进步太慢,很担心自己在学弟学妹们面前丢人,所以天天熬夜在实验室里训练。
某一天wzc学长训练得实在太累了,居然在大白天做起了梦。
在梦里面,wzc学长在第一天有一个初始的码力值x,第二天的时候码力值变为了x2,第三天的时候码力值变为了x3…第i天的时候码力值变为了xi。
现在wzc学长想知道第i天的时候,他的码力值是多少。由于这个值可能非常大,请输出对9999999967取模的结果。
输入描述:
第一行一个整数T,代表输入数据组数。(1≤T≤1×103)
接下来T行,每行两个整数x和i,代表第一天的初始码力值,和所要求的是第几天的码力值。
(1≤x≤10,不会吧不会吧,不会真的有人这么弱吧)
(1≤i≤1×109)
输出描述:
输出T行,每行一个整数,代表xi对9999999967取模的结果。
示例1
输入
2
1 1000000000
2 3
输出
1
8