数论模板初期...

大小只有10k左右....并不是很全....里面有手打的modint,bitset和hashmap(O(1)清空..)

#include <cmath>
#include <cstdio>
#include <cstring>
#define fon(i,s)    for(int i=0;i<s; ++i)
#define fone(i,s)   for(int i=0;i<=s;++i)
#define fox(i,f,t)  for(int i=f;i<t; ++i)
#define foxe(i,f,t) for(int i=f;i<=t;++i)
#define fdn(i,s)    for(int i=s;i;   --i)
#define fdne(i,s)   for(int i=s;~i;  --i)
#define fdx(i,f,t)  for(int i=f;i>t; --i)
#define fdxe(i,f,t) for(int i=f;i>=t;--i)
namespace _nt{
	#define mod 998244353
	#define modll 998244353
	struct intm{
		int n;
		inline intm(){ n=0; }
		inline intm(int nx){ n=nx%mod; }
		inline intm(long long nx){ n=nx&((2<<31)-1); }
		friend inline intm operator+(intm a,intm b){ return intm(a.n+b.n); }
		friend inline intm operator-(intm a,intm b){ return intm(a.n-b.n+mod); }
		friend inline intm operator*(intm a,intm b){ return intm((long long)a.n*b.n&modll); }
		friend inline intm operator^(intm a,int b){
			intm u(1);
			while(b){
				if(b&1) u=u*a;
				a=a*a,b>>=1;
			}
			return u;
		}
		friend inline intm operator^(intm a,long long b){
			intm u(1);
			while(b){
				if(b&1) u=u*a;
				a=a*a,b>>=1;
			}
			return u;
		}
		friend inline intm operator^(intm a,unsigned long long b){
			intm u(1);
			while(b){
				if(b&1) u=u*a;
				a=a*a,b>>=1;
			}
			return u;
		}
		friend inline intm operator^(intm a,unsigned int b){
			intm u(1);
			while(b){
				if(b&1) u=u*a;
				a=a*a,b>>=1;
			}
			return u;
		}
		friend inline intm operator^(intm a,intm b){
			return a^(b.n);
		}
		friend inline intm operator~(intm a){
			return a^(mod-2);
		}
		friend inline intm operator/(intm a,intm b){
			return a*(~b);
		}
	};
	struct bitset_u{
		unsigned long long u;
		inline bitset_u(){
			u=0ll;
		}
		inline bitset_u(unsigned long long a){u=a;}
		inline bool get(int n){
			return (u>>n)&1;
		}
		inline void set(int n,bool p){
			u=(u|(1<<n))&p<<n;
		}
		inline bitset_u operator<<(int n){
			return bitset_u(u<<n);
		}
		inline bitset_u operator>>(int n){
			return bitset_u(u>>n);
		}
		inline bitset_u operator^ (bitset_u n){
			return bitset_u(u^n.u);
		}
		inline bitset_u operator& (bitset_u n){
			return bitset_u(u&n.u);
		}
		inline bitset_u operator| (bitset_u n){
			return bitset_u(u|n.u);
		}
		inline bitset_u operator~ (){
			return bitset_u(~u);
		}
	};
	#define maxn 20000010
	struct linear_sieve{
		bool is[maxn];
		int primes[maxn/10],primelen;
		inline void operator()(){
			is[1]=1;
			for(int i=2;i<maxn;++i){
				if(!is[i]) primes[primelen++]=i;
				for(int j=0;j<primelen;++j){
					if(i*primes[j]>=maxn) break;
					if(i%primes[j]) is[i*primes[j]]=1; else {
						is[i*primes[j]]=1;
						break;
					}
				}
			}
		}
	} ls;
	struct linear_sieve_phi{
		bool is[maxn];
		int primes[maxn/10],primelen,phi[maxn];
		inline void operator()(){
			is[1]=1;
			phi[1]=0;
			for(int i=2;i<maxn;++i){
				if(!is[i]) primes[primelen++]=i,phi[i]=i-1;
				for(int j=0;j<primelen;++j){
					if(i*primes[j]>=maxn) break;
					if(i%primes[j]) is[i*primes[j]]=1,phi[i*primes[j]]=phi[i]*(primes[j]-1); else {
						is[i*primes[j]]=1,phi[i*primes[j]]=phi[i]*primes[j];
						break;
					}
				}
			}
		}
	};
	struct linear_sieve_mu{
		bool is[maxn];
		int primes[maxn/10],primelen,mu[maxn];
		inline void operator()(){
			is[1]=1;
			mu[1]=1;
			for(int i=2;i<maxn;++i){
				if(!is[i]) primes[primelen++]=i,mu[i]=-1;
				for(int j=0;j<primelen;++j){
					if(i*primes[j]>=maxn) break;
					if(i%primes[j]) is[i*primes[j]]=1,mu[i*primes[j]]=-mu[i]; else {
						is[i*primes[j]]=1,mu[i*primes[j]]=0;
						break;
					}
				}
			}
		}
	};
	struct linear_sieve_ds{
		bool is[maxn];
		int primes[maxn/10],primelen,mu[maxn],ds[maxn],dp[maxn];
		inline void operator()(){
			is[1]=1;
			ds[1]=1;
			for(int i=2;i<maxn;++i){
				if(!is[i]) primes[primelen++]=i,mu[i]=-1;
				for(int j=0;j<primelen;++j){
					if(i*primes[j]>=maxn) break;
					if(i%primes[j]) is[i*primes[j]]=1,ds[i*primes[j]]=ds[i]*dp[i],dp[i*primes[j]]=2; else {
						is[i*primes[j]]=1,dp[i*primes[j]]=dp[i]+1;
						break;
					}
				}
			}
			for(int i=2;i<maxn;++i) ds[i]*=dp[i];
		}
	};
	#define maxm 10000005
	struct linear_inverse{
		long long inv[maxm];
		inline void mx(int n,long long m){
			inv[1]=1;
			for(int i=1;i<=n;++i){
				inv[i]=((-(m/i)*inv[(int)(m%i)])%m+m)%m;
			}
		}
	};
	typedef unsigned long long ll;
	ll dev(ll n){//count number of divisors O(sqrt(n))
		ll res=1,t=2,p;
		while(n*n>=t){
			p=1;
			while(!(n%t)){
				n/=t;
				++p;
			}
			res*=p;
			++t;
		}
		if(n!=1) res<<=1;
		return res;
	}
	ll sigma(ll n){//count sum of divisors  O(sqrt(n))
		ll res=1,t=2,tp;
		while(n*n>=t){
			tp=t;
			while(!(n%t)){
				n/=t;
				tp*=t;
			}
			res*=(tp-1)/(t-1);
			++t;
		}
		if(n!=1) res*=n+1;
		return res;
	}
	//modmul O(1)
	inline ll modmul(ll a,ll b,ll p){ return ((a*b-(ll)(((long double)a*b)/p)*p)%p+p)%p; }
	inline ll modpow(ll a,ll e,ll p){//fast power O(log e)
		ll q=1;
		while(e){
			if(e&1) q=modmul(q,a,p);
			a=modmul(a,a,p);
			e>>=1;
		}
		return q;
	}
	inline bool Miller_Rabin_Single(ll a,ll u,ll r,ll n){//primality test for (si-)prime u*2^r+1 base a
		ll k=modpow(a,u,n),pre=k;
		while(r--){
			k=modmul(k,k,n);
			if(k==1ll && pre!=1ll && pre!=n-1) return 0;
			pre=k;
		}
		return k==1ll;
	}
	bool Miller_Rabin(ll n){//test primality
		if(n==2 || n==3 || n==5 || n==7 || n==11) return 1;
		if(!(n&1) || !(n%3) || !(n%5) || !(n%7) || !(n%11)) return 0;
		ll u=n-1,r=0;
		while(!(u&1)) u>>=1,++r;
		if(!Miller_Rabin_Single(2,u,r,n)) return 0;
		if(!Miller_Rabin_Single(1215,u,r,n)) return 0;
		if(!Miller_Rabin_Single(34862,u,r,n)) return 0;
		if(!Miller_Rabin_Single(574237825,u,r,n)) return 0;
		return 1;
	}
	template<class T>inline T gcd(T a,T b){//gcd O(log n)
		T c;
		while(a){
			c=b%a;
			b=a,a=c;
		}
		return b;
	}
	ll Polard_rho(ll n,ll c,ll u){//factor long long O(n^(1/4))
		ll i=1,k=2;
		ll y=u,x0=u;
		while(1){
			++i;
			x0=(modmul(x0,x0,n)+c)%n;
			ll d=gcd(y-x0,n);
			if(d!=1 && d!=n) return d;
			if(y==x0) return n;
			if(i==k) y=x0,k+=k;
		}
	}
	#define ed 300005
	#define mi 1333357
	struct hashmap{//hashmap with O(1) clearing
		int next[ed][4],h[mi],u,x;
		inline void operator()(){
			u=0,next[0][2]=-1,++x;
		}
		inline void operator()(long long n,int k){
			int q=n%mi,t=h[q];
			while(t && next[t][0]!=n && next[t][3]==x) t=next[t][1];
			if(!t || next[t][3]!=x){
				++u;
				next[u][0]=n,next[u][1]=h[q],t=u,next[u][3]=x;
				h[q]=u;
			}
			next[t][2]=k;
		}
		inline int operator[](long long n){
			int q=n%mi,t=h[q];
			while(t && next[t][0]!=n && next[t][3]==x) t=next[t][1];
			if(next[t][3]!=x) return -1;
			return next[t][2];
		}
	};
	inline unsigned int sqrt(ll x){ return (unsigned int)sqrt((double)x*x); }
	struct BSGS{//Finding discrete logarithm
		hashmap q;
		inline ll operator()(ll a,ll b,ll p){
			q(),q(1,0);
			int m=sqrt(p);
			ll v=modpow(a,p-m-1,p),e=1;
			fox(i,1,m){
				e=modmul(a,e,p);
				q(e,i);
			}
			fon(i,m){
				ll j=q[b];
				if(~j) return i*m+j;
				b=modmul(b,v,p);
			}
			return -1;
		}
	} Baby_Step_Giant_Step;
	struct _pext_euc{//Solving ax+by=1
		ll x,y;
		ll exgcd(ll a,ll b){
			ll t=0,d=0;
			if(b){
				d=exgcd(b,a%b);
				t=x;
				x=y;
				y=t-(a/b)*y;
				return d;
			}else{
				x=1,y=0;
				return a;
			}
		}
		inline ll operator()(ll a,ll b){
			return exgcd(a,b);
		}
	} Extended_Euclid;
	ll inv_fast(ll a,ll p){//calculate inverse O(log n) with exgcd
		Extended_Euclid(a,p);
		return (Extended_Euclid.x%p+p)%p;
	}
	ll eular_phi(ll a){//calculate eular phi O(sqrt(n))
		ll i=2,t,r=1;
		while(i*i<=a){
			if(a%i){ ++i;continue;}else{
				t=i-1,a=a/i;
				while(!(a%i)) a=a/i,t=t*i;
				++i,r=r*t;
			}
		}
		if(a) r=r*(a-1);
		return r;
	}
	struct exBSGS{
		ll operator()(ll a,ll b,ll p){
			ll k=0,u,l=1,x=1,A=a,B=b,P=p,ans=0;
			if(B==1) return 0;
			if(A==B) return 1;
			while((u=gcd(a,p))!=1){
				if(b%u) return -1;
				++k,l=a/u,b=b/u,p=p/u;
				x=modmul(l,x,p);
				if(x==b) ans=k;
			}
			ll y=inv_fast(x,p);
			b=modmul(b,y,p);
			if(!ans) ans=Baby_Step_Giant_Step(a,b,p);
			a=A,b=B;
			fox(i,2,k){
				a=modmul(a,A,p);
				if(a==b) return i;
			}
			return ans+k;
		}
	} extended_Baby_Step_Giant_Step;
	ll least_primitive_root_for_prime(ll n){//O(g sqrt(n))
		fox(i,2,n){
			if(Baby_Step_Giant_Step(i,1,n)==n-1) return i;
		}
		return -1;
	}
	ll least_primitive_root(ll n){
		ll p=eular_phi(n);
		fox(i,2,n){
			if(extended_Baby_Step_Giant_Step(i,1,n)==p) return i;
		}
		return -1;
	}
	struct Comb_Number_Small1{//O(mn)-O(1) p none
		ll CC[2002][2002];
		inline void init(int n,ll p){
			CC[1][1]=1;
			foxe(i,1,n){
				foxe(j,1,i){
					CC[i][j]=(CC[i-1][j-1]+CC[i-1][j])%p;
				}
			}
		}
		inline ll operator()(int n,int m){
			return CC[n][m];
		}
	};
	struct Comb_Number_Small2{//O(n)-O(1) p prime
		linear_inverse li;
		ll facn[maxm],infacn[maxm],pp;
		inline void init(int n,ll p){
			li.mx(n,p);
			facn[1]=1,pp=p;
			foxe(i,2,n) facn[i]=modmul(facn[i-1],i,p),infacn[i]=modmul(infacn[i-1],li.inv[i],p);
		}
		inline ll operator()(int n,int m){
			if(m>n) return 0;
			ll a=modmul(infacn[m],infacn[n-m],pp);
			return modmul(facn[n],a,pp);
		}
	};
	struct Comb_Number_Lucas{
		Comb_Number_Small2 b;
		ll pp;
		inline void init(ll n,ll p){
			b.init((int)p,p);
			pp=p;
		}
		inline ll operator()(int n,int m){
			ll ans=1,kk;
			while(m){
				kk=b(n%pp,m%pp);
				ans=modmul(kk,ans,pp);
				if(!ans) return 0;
				n/=pp,m/=pp;
			}
			return ans;
		}
	};
	struct Comb_Number_factor{
		linear_sieve s;
		int count[2000010];
		inline void init(){
			s();
		}
		inline int calcp(int n,int p){
			int res=0,pp=p;
			while(n>=pp) res+=n/pp,pp=p*pp;
			return res;
		}
		inline ll operator()(int n,int m,ll p){
			int k=m-n;
			for(int i=0;s.primes[i]<=n;++i) count[i]=calcp(n,s.primes[i]);
			for(int i=0;s.primes[i]<=m;++i) count[i]-=calcp(m,s.primes[i]);
			for(int i=0;s.primes[i]<=k;++i) count[i]-=calcp(k,s.primes[i]);
			ll res=1,pq;
			for(int i=0;s.primes[i]<=n;++i){
				pq=modpow(s.primes[i],count[i],p);
				res=modmul(res,pq,p);
			}
			return res;
		}
	};
	#define crtn 400005
	struct CRT{
		ll de[crtn],nn[crtn];//product of de should be within range<long long>()
		inline ll operator()(int n){
			ll M=1,ans=0;
			fon(i,n) M*=de[n];
			fon(i,n){
				ll t=M/de[n],inv=inv_fast(t,de[n]);
				ans=(ans+t*inv*nn[n])%M;
			}
			return (ans+M)%M;
		}
	};
	struct _solve_linear_congruent_equations{
		ll de[crtn],nn[crtn];
		inline void single(ll &x,ll &y,ll c,ll d){
			ll a=x,b=y;
			x=gcd(b,d);
			y=(ll)(((long double)a*b)/x);//lcm a,b
			ll t=inv_fast(b,d),t2=c-a;
			x=modmul(t,t2,y);
		}
		inline ll operator()(int n){
			fox(i,1,n) single(nn[0],de[0],nn[i],de[i]);
			return nn[0];
		}
	};
	ll lcm(ll a,ll b){
		ll t=gcd(a,b);
		return (ll)(((long double)a*b)/t);
	}
}
int main(){
}
posted @ 2015-07-19 21:26  zball  阅读(232)  评论(1编辑  收藏  举报