title :
The King of electrical tones
The following:
Finding the first n Xiangxiang multiplication and modulus of a sequence
Ideas :
①, the multiplication of this problem is a long long , can be solved by the idea of fast power (according to the number of one of the number of split). Of course your multiplication will be more of a log complexity ...
②,O (1) fast multiplication: An O (1) complexity solution for integer multiplication modulo (it is also applicable for the integral type of the four bits):
From the year of the country Training Team paper: Cochang: "Some methods and techniques for the optimization of the bottom of the program" (refer to the original link)
Long Long ll; #define MOL 123456789012345LLInline ll mul_mod_ll (ll A,ll b) { = (ll) floor (A * (double0.5); c9/>= A * b-d * MOL; if 0) ret = MOL; return ret;}
View Code
③:DLs A sentence solution (of course, can not understand ...) )
refer to a blog Montgomery Modular multiplication (of course, also can not understand ...) Japanese)
The puzzle: (DLS Code)
#include <bits/stdc++.h>using namespacestd;#defineRep (i,a,n) for (int i=a;i<n;i++)#definePer (i,a,n) for (int i=n-1;i>=a;i--)#definePB Push_back#defineMP Make_pair#defineAll (x) (x). Begin (), (x). End ()#defineFi first#defineSe Second#defineSZ (x) ((int) (x). Size ())typedef vector<int>Vi;typedefLong LongLl;typedef pair<int,int>PII;Constll mod=1000000007; ll Powmod (ll A,ll b) {ll res=1; a%=mod; ASSERT (b>=0); for(; b;b>>=1){if(b&1) Res=res*a%mod;a=a*a%mod;}returnRes;} ll GCD (ll A,ll b) {returnB?GCD (b,a%b): A;}//Headtypedef unsignedLong Longu64;typedef __int128_t i128;typedef __uint128_t u128;int_,k;u64 a0,a1,m0,m1,c,m;structMod64 {Mod64 (): N_ (0{} Mod64 (u64 N): N_ (init (n)) {}StaticU64 Init (u64 W) {returnReduce (u128 (w) *R2); } Static voidSet_mod (u64 m) {mod=m; ASSERT (mod&1); INV=m; Rep (I,0,5) inv*=2-inv*m; R2=-u128 (m)%m; } Staticu64 Reduce (u128 x) {U64 y=u64 (x>> -)-u64 ((u128 (U64 (x) *INV) *mod) >> -); returnll (Y) <0? y+mod:y; } Mod64&operator+ = (Mod64 rhs) {n_+=rhs.n_-mod;if(LL (N_) <0) N_+=mod;return* This; } Mod64operator+ (MOD64 RHS)Const{returnMOD64 (* This)+=RHS;} Mod64&operator-= (Mod64 rhs) {n_-=rhs.n_;if(LL (N_) <0) N_+=mod;return* This; } Mod64operator-(MOD64 RHS)Const{returnMOD64 (* This)-=RHS;} Mod64&operator*= (Mod64 rhs) {n_=reduce (u128 (n_) *rhs.n_);return* This; } Mod64operator* (MOD64 RHS)Const{returnMOD64 (* This)*=RHS;} U64Get()Const{returnreduce (n_);} StaticU64 mod,inv,r2; U64 N_;}; U64 MOD64::MOD,MOD64::INV,MOD64::R2; U64 pmod (u64 a,u64 b,u64 p) {U64 d= (U64) Floor (A * (Long Double) b/p+0.5); LL ret=a*b-d*p; if(ret<0) ret+=p; returnret;} voidBruteforce () {u64 ans=1; for(intI=0; i<=k;i++) {ans=Pmod (ans,a0,m); U64 A2=pmod (m0,a1,m) +pmod (m1,a0,m) +b; while(a2>=m) a2-=M; A0=A1; a1=A2; } printf ("%llu\n", ans);} intMain () { for(SCANF ("%d", &_); _;_--) {scanf ("%llu%llu%llu%llu%llu%llu%d",&a0,&a1,&m0,&m1,&c,&m,&k); Mod64::set_mod (M); Mod64 A0 (A0), A1 (A1), M0 (M0), M1 (M1), C (c), ans (1), A2 (0); for(intI=0; i<=k;i++) {ans=ans*A0; A2=m0*a1+m1*a0+C; A0=A1; a1=A2; } printf ("%llu\n", ans.Get()); }}
View Code
Reference :
On some methods and techniques of the bottom-up optimization of programs
In addition to the calculation of the remainder more high-speed
Modular arithmetic and Montgomery form for fast mode multiplication