__int128
使用方式
正常来说,\(\text{unsigned long long}\) 已经是可以定义的最大的类型了,但是如果数据范围超过了 \(2^{64}\) 就会爆掉。如果要处理比其大一点又不是那么大的数,就可以使用 \(\text{\_\_int128}\)。
NOI 系列赛事中都可以正常使用 \(\text{\_\_int128}\)。
\(\text{\_\_int128}\) 就是占用 \(128\) 位的整数存储类型。存储范围是 \(-2^{127}\sim2^{127}-1\)。如果使用了 \(\text{unsigned\ \_\_int128}\),则范围变成 \(0\sim2^{128}\),即约 \(39\) 位数。
\(\text{\_\_int128}\) 的使用方法与 \(\text{long\ long}\)、\(\text{int}\) 等无异,但无法使用 \(\text{cin}\) 或 \(\text{scanf}\) 等输入输出,需要使用快读快写。
快读快写模板
LLL quick_read()
{
LLL x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+(ch-'0');
ch=getchar();
}
return x*f;
}
void quick_write(LLL x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>=10) quick_write(x/10);
putchar((x%10)+'0');
}
例题
这题有两种写法,一种是龟速乘,另一种是 \(\text{\_\_int128}\)。作为例题,仅给出 \(\text{\_\_int128}\) 的两种写法。
第一种是直接将 \(a\),\(b\),和 \(p\) 定义为 \(\text{\_\_int128}\) 的类型,相乘取模后输出。
#include<iostream>
#include<cstdio>
using namespace std;
typedef __int128 LLL;
LLL a,b,p,ans;
LLL quick_read()
{
LLL x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+(ch-'0');
ch=getchar();
}
return x*f;
}
void quick_write(LLL x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>=10) quick_write(x/10);
putchar((x%10)+'0');
}
int main()
{
a=quick_read(),b=quick_read(),p=quick_read();
ans=(a*b)%p;
quick_write(ans);
return 0;
}
还有另外一种更简便的方法,由于我们输入输出的数范围都不超过 \(\text{long\ long}\) 范畴,只是相乘时会爆,所以可以在相乘时强制转换为类型 \(\text{\_\_int128}\),取模后再转回 \(\text{long\ long}\) 输出。
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef __int128 LLL;
ll a,b,p,ans;
int main()
{
scanf("%lld%lld%lld",&a,&b,&p);
ans=((LLL)a*(LLL)b)%p;
printf("%lld",ans);
return 0;
}

浙公网安备 33010602011771号