# Modular Arithmetic# Binary Multiplication# Number Theory

b430 - 簡單乘法

🔗 前往 ZeroJudge 原題

題目描述

題目要求計算 (a * b) % n 的值,其中 abn 都是大整數(最大可達 10^18)。由於直接計算 a * b 可能會超出 64 位元的範圍,因此需要使用模運算的一些技巧來避免溢位。

解題思路

程式碼使用二進位乘法來計算 a * b % n。核心思想是將 b 轉換為二進位表示,然後根據 b 的每一位,將 a 乘以 2 的冪次,並累加結果,所有中間結果都進行模 n 運算,以防止溢位。mod 函數實現了這個二進位乘法和模運算。readwrite 函數分別用於快速讀取和輸出 long long int 數值。

複雜度分析

  • 時間複雜度: O(log b) (其中 b 是第二個輸入數,因為迴圈迭代次數與 b 的二進位表示的長度成正比)
  • 空間複雜度: O(1) (使用了固定大小的陣列來儲存數字的位數,因此空間複雜度是常數)

程式碼

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <stdio.h>
inline long long int mod(long long int a,long long int b,long long int c){
	long long int tmp=0;
	for(;b;b>>=1,a<<=1,a=(a>=c)?a-c:a){
		if(b&1){
			tmp+=a;
			if(tmp>=c)
				tmp-=c;
		}
	}
	return tmp;
}
inline void write(long long int x) {
	if(x==0)putchar_unlocked('0');
	long long int stk[20],*ptr(&stk[0]);
	while(x){*ptr=x%10;x/=10;++ptr;}
	while(--ptr>=(&stk[0])){putchar_unlocked(*ptr+'0');}
}
inline long long int read(){
	long long int a(0);
	char c('0');
	while(c>='0'){
		a=(a<<3)+(a<<1)+c-'0';
		c=getchar_unlocked();
	}
	return a;
}
int main(){
	long long int a,b,c;
	while(a=read(),b=read(),c=read()){
		write(mod(a%c,b%c,c));
		putchar_unlocked('\n');
	}
}

Discussion