tozangezan's diary

勝手にソースコードをコピペして利用しないでください。

AOJ 2353: Four Arithmetic Operations

気がついたら簡単だった。
二つの1000000より大きい素数modで答えを求めてから二つのmodどちらにも当てはまるものを答えるだけ(中国剰余定理から当たり前)
負が入力に入るのがちょっと厄介。

だけど、どうやってデータセットを作っているのだろう。気になる。多倍長でがんばってるんだろうか。

#include<stdio.h>
#include<algorithm>
using namespace std;
long long mod1=1000033;
long long mod2=1000037;
long long inv(long long x,int t){
	long long ret=1;
	long long now=x;
	long long mod=mod1;
	if(t==2)mod=mod2;
	int pow=mod-2;
	while(pow){
		if(pow%2){
			ret=ret*now%mod;
		}
		now=now*now%mod;
		pow/=2;
	}
	return ret;
}
int main(){
	int a;
	scanf("%d",&a);
	long long v1=0;
	long long v2=0;
	for(int i=0;i<a;i++){
		int p,q;
		scanf("%d%d",&p,&q);
		if(p==1){
			v1=(v1+mod1+q%mod1)%mod1;
			v2=(v2+mod2+q%mod2)%mod2;
		}
		if(p==2){
			v1=(v1+mod1-q%mod1)%mod1;
			v2=(v2+mod2-q%mod2)%mod2;
		}
		if(p==3){
			v1=(v1*(q%mod1+mod1))%mod1;
			v2=(v2*(q%mod2+mod2))%mod2;
		}
		if(p==4){
			v1=(v1*inv((q%mod1+mod1),1))%mod1;
			v2=(v2*inv((q%mod2+mod2),2))%mod2;
		}
	}
	//printf("%lld %lld\n",v1,v2);
	for(long long x=-1000000;x<=1000000;x++){
		long long N=x*mod1+v1;
		long long M=(N%mod2+mod2)%mod2;
		if(M==v2&&-(1LL<<31)<=N&&N<(1LL<<31)){
			printf("%lld\n",N);return 0;
		}
	}
}