__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;
} 
posted @ 2024-08-12 11:19  MinimumSpanningTree  阅读(59)  评论(0)    收藏  举报