神奇的__int128(幕乘——大mod)

31 篇文章 0 订阅
30 篇文章 0 订阅

今天去做了几道签到题,发现自己的幕乘居然有问题
我的幕乘板子:

#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值