板子们

非旋 treap (fhq treap)

namespace FHQ{
	int r[N],v[N],s[N],c[N][2],ind;ll sum[N];
	inline int brand(){
		return((rand()&0x7fff)<<16)+((rand()&0x7fff)<<1)+(rand()&1);
	}
	inline int newnode(int _v){
		r[++ind]=brand(),s[ind]=1,v[ind]=sum[ind]=_v;return ind;
	}
	inline void update(int u){
		s[u]=s[c[u][0]]+s[c[u][1]]+1;
		sum[u]=sum[c[u][0]]+sum[c[u][1]]+v[u];
	}
	int merge(int a,int b){
		if(!a||!b)return a+b;
		if(r[a]<r[b]){
			c[a][1]=merge(c[a][1],b);
			update(a);
			return a;
		}else{
			c[b][0]=merge(a,c[b][0]);
			update(b);
			return b;
		}
	}
	void splitv(int a,int b,int&l,int&r){
		if(!a){l=r=0;return;}
		if(v[a]<=b)l=a,splitv(c[a][1],b,c[a][1],r);
		else r=a,splitv(c[a][0],b,l,c[a][0]);
		update(a);
	}
	void splits(int a,int b,int&l,int&r){
		if(!a){l=r=0;return;}
		if(b<=s[c[a][0]])r=a,splits(c[a][0],b,l,c[a][0]);
		else l=a,splits(c[a][1],b-s[c[a][0]]-1,c[a][1],r);
		update(a);
	}
	void insert(int&u,int x){
		int a=0,b=0;
		splitv(u,x,a,b);
		u=merge(a,merge(newnode(x),b));
	}
	void erase(int&u,int x){
		int a=0,b=0,c=0;
		splitv(u,x-1,a,b);
		splits(b,1,b,c);
		u=merge(a,c);
	}
	void erase_all(int&u,int x){
		int a=0,b=0,c=0;
		splitv(u,x-1,a,b);
		splitv(u,x,b,c);
		u=merge(a,c);
	}
	int kth(int&u,int x){
		int a=0,b=0,c=0,res=0;
		splits(u,x-1,a,b);
		splits(b,1,b,c);
		res=v[b];
		u=merge(a,merge(b,c));
		return res;
	}
};

多项式 inv,ln,exp (ntt)

#include<bits/stdc++.h>
#define D(...) fprintf(stderr,__VA_ARGS__)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
typedef vector<int> poly;
const int P=998244353;
int fpow(int a,int b){int res=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)res=1ll*res*a%P;return res;} 
void pt(const poly&a){for(int i=0;i<(int)a.size();++i)D("%d ",a[i]);D("\n");}
int getlim(int n){int x=1;while(x<=n)x<<=1;return x;}
void ntt(poly&a,int g,int lim){
	a.resize(lim);
	for(int i=0,j=0;i<lim;++i){
		if(i<j)swap(a[i],a[j]);
		for(int k=lim>>1;(j^=k)<k;k>>=1);
	}
	poly w(lim>>1);w[0]=1;
	for(int i=1;i<lim;i<<=1){
		for(int j=1,wn=fpow(g,(P-1)/(i<<1));j<i;++j)w[j]=1ll*w[j-1]*wn%P;
		for(int j=0;j<lim;j+=i<<1)
			for(int k=0;k<i;++k){
				int x=a[j+k],y=1ll*a[i+j+k]*w[k]%P;
				a[j+k]=(x+y)%P,a[i+j+k]=(x-y+P)%P;
			}
	}
	if(g==332748118)for(int i=0,I=fpow(lim,P-2);i<(int)a.size();++i)a[i]=1ll*a[i]*I%P;
}
poly pmul(poly a,poly b){
	int need=(int)a.size()+b.size()-1,lim=getlim(need);
	ntt(a,3,lim),ntt(b,3,lim);
	for(int i=0;i<lim;++i)a[i]=1ll*a[i]*b[i]%P;
	ntt(a,332748118,lim);
	return a.resize(need),a;
}
poly padd(poly a,poly b){
	if(a.size()<b.size()){
		for(int i=0;i<(int)a.size();++i)(b[i]+=a[i])%=P;
		return b;
	}else{
		for(int i=0;i<(int)b.size();++i)(a[i]+=b[i])%=P; 
		return a;
	}
}
poly pinv(const poly&a,int n=-1){
	if(n==-1)n=a.size();
	if(n==1)return poly(1,fpow(a[0],P-2));
	poly b=pinv(a,(n+1)>>1),tmp=poly(a.begin(),a.begin()+n);
	int lim=getlim(n*2-2);
	ntt(b,3,lim),ntt(tmp,3,lim);
	for(int i=0;i<lim;++i)b[i]=(2-1ll*b[i]*tmp[i]%P+P)%P*b[i]%P;
	ntt(b,332748118,lim);
	return b.resize(n),b;
}
poly pdao(const poly&a){
	poly b((int)a.size()-1);
	for(int i=1;i<(int)a.size();++i)b[i-1]=1ll*a[i]*i%P;
	return b;
}
poly pji(const poly&a){
	poly b((int)a.size()+1);
	for(int i=0;i<(int)a.size();++i)b[i+1]=1ll*a[i]*fpow(i+1,P-2)%P;
	return b;
}
poly pln(const poly&a){
	poly b(pmul(pdao(a),pinv(a)));
	b.resize((int)a.size()-1);
	return pji(b);
}
poly pexp(const poly&a,int n=-1){
	if(n==-1)n=a.size();
	if(n==1)return poly(1,1);
	poly b=pexp(a,(n+1)>>1),c(b);
	c.resize(n),c=pln(c),--c[0];
	for(int i=0;i<n;++i)c[i]=(a[i]-c[i]+P)%P;
	poly d(pmul(b,c));
	return d.resize(n),d;
}
int main(){
	
	return 0;
}

最大流

#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=100005;
int n,m,S,T,dep[N],gap[N];bool vis[N];
struct ed{int nxt,to,v;}G[N*10];int lnk[N],cur[N],pp=1;
void ae(int k1,int k2,int k3){
	G[++pp]=(ed){lnk[k1],k2,k3},lnk[k1]=pp;
	G[++pp]=(ed){lnk[k2],k1, 0},lnk[k2]=pp;
}
int dfs(int k1,int val){
	if(k1==T)return val;
	int v=val;
	for(int&i=cur[k1];i;i=G[i].nxt){
		int j=G[i].to;
		if(dep[k1]==dep[j]+1&&G[i].v){
			int f=dfs(j,std::min(v,G[i].v));
			G[i].v-=f,G[i^1].v+=f,v-=f;
			if(!v)return val;
		}
	}
	if(!--gap[dep[k1]++])dep[S]=T+1;
	++gap[dep[k1]],cur[k1]=lnk[k1];
	return val-v;
}
void dfs2(int k1){
	vis[k1]=1;
	for(int i=lnk[k1];i;i=G[i].nxt){
		int j=G[i].to;
		if(G[i].v==0||vis[j])continue;
		dfs2(j);
	}
}
int main(){
	scanf("%d%d",&n,&m);S=n*2+1,T=n*2+2;
        //
	int res=0;
	memcpy(cur,lnk,sizeof(lnk)),gap[0]=T;
	while(dep[S]<=T){
		res+=dfs(S,0x3f3f3f3f);
	}
	printf("%d\n",res);
	return 0;
}

费用流

typedef long long LL;
const int INF=0X3F3F3F3F;
const LL INFLL=0X3F3F3F3F3F3F3F3FLL;
struct MCMF{
	int S,T;
	vector<int>lnk,pre;
	int mf;
	LL mc;
	int op;
	// min-cost-max-flow if op==+1 (default)
	// max-cost-max-flow if op==-1
	struct edge{
		int nxt,to,w;
		LL c;
	};
	vector<edge>G;
	MCMF(){}
	MCMF(int n,int _op=1){
		init(n,_op);
	}
	void init(int n,int _op=1){
		S=0,T=n+1,op=_op;
		lnk.assign(T+1,-1);
		G.clear();
	}
	void ae(int k1,int k2,int k3,LL k4){
		k4*=op;
		G.push_back((edge){lnk[k1],k2,k3,k4}),lnk[k1]=((int)G.size())-1;
		G.push_back((edge){lnk[k2],k1,0,-k4}),lnk[k2]=((int)G.size())-1;
	}
	vector<LL>dis;
	vector<bool>vis;
	queue<int>q;
	bool spfa(){
		pre.assign(T+1,-1);
		dis.assign(T+1,INFLL);
		vis.assign(T+1,0);
		while(!q.empty())q.pop();
		dis[S]=0;
		vis[S]=1;
		q.push(S);
		while(!q.empty()){
			int k1=q.front();
			vis[k1]=0;
			q.pop();
			for(int i=lnk[k1];i!=-1;i=G[i].nxt)if(G[i].w&&dis[k1]+G[i].c<dis[G[i].to]){
				dis[G[i].to]=dis[k1]+G[i].c;
				pre[G[i].to]=i;
				if(!vis[G[i].to]){
					vis[G[i].to]=1;
					q.push(G[i].to);
				}
			}
		}
		return dis[T]!=INFLL;
	}
	void zg1(){
		int f=INF;
		for(int i=pre[T];i!=-1;i=pre[G[i^1].to])f=min(f,G[i].w);
		for(int i=pre[T];i!=-1;i=pre[G[i^1].to])G[i].w-=f,G[i^1].w+=f;
		mf+=f;
		mc+=f*dis[T];
	}
	vector<int>dep,gap,cur;
	int SAP(int k1,int k2){
		if(k1==T)return k2;
		int k3=k2;
		for(int&i=cur[k1];i!=-1;i=G[i].nxt)if(dep[k1]==dep[G[i].to]+1&&G[i].w&&dis[k1]+G[i].c==dis[G[i].to]){
			int f=SAP(G[i].to,min(k3,G[i].w));
			G[i].w-=f,G[i^1].w+=f,k3-=f;
			if(k3==0)return k2;
		}
		if(dep[k1]<=T&&!--gap[dep[k1]++])dep[S]=T+1;
		if(dep[k1]<=T)++gap[dep[k1]];
		cur[k1]=lnk[k1];
		return k2-k3;
	}
	void zg2(){
		cur=lnk;
		dep.assign(T+1,0);
		gap.assign(T+1,0);
		gap[0]=T+1;
		int res=0;
		while(dep[S]<=T){
			res+=SAP(S,INF);
		}
		mf+=res;
		mc+=res*dis[T];
	}
	void sol(){
		mc=0,mf=0;
		while(spfa()){
			//zg1();
			zg2();
		}
		mc*=op;
	}
};

扩展卢卡斯定理 (exlucas)

#include<cstdio>
#include<vector>
#include<algorithm>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long ll;
ll n,m;int p;
int fastpow(int a,ll b,int p){
	int res=1;
	for(;b;b>>=1,a=1ll*a*a%p)if(b&1)res=1ll*res*a%p;
	return res;
}
void exgcd(int a,int b,int&x,int&y){
	if(!b){x=a,y=0;return;}
	exgcd(b,a%b,x,y);
	int t=x;
	x=y,y=t-a/b*y;
}
int inv(int a,int b){
	int x,y;
	exgcd(a,b,x,y);
	return (x%b+b)%b;
}
int jc(ll n,int p,int k){
	if(!n)return 1;
	int res=1;
	rep(i,1,k)if(i%p)res=1ll*res*i%k;
	res=fastpow(res,n/k,k);
	rep(i,1,n%k)if(i%p)res=1ll*res*i%k;
	return 1ll*res*jc(n/p,p,k)%k;
}
int C(ll n,ll m,int p,int k){
	int a=jc(n,p,k),b=jc(m,p,k),c=jc(n-m,p,k);
	ll sum=0;
	for(ll i=m;i;i/=p)sum-=i/p;
	for(ll i=n-m;i;i/=p)sum-=i/p;
	for(ll i=n;i;i/=p)sum+=i/p;
	return 1ll*a*fastpow(p,sum,k)%k*inv(b,k)%k*inv(c,k)%k;
}
int crt(int x,int p,int k){
	return 1ll*x*(p/k)%p*inv(p/k,k)%p;
}
int exlucas(ll n,ll m,int p){
	int x=p,ans=0;
	rep(i,2,p/i){
		int k=1;
		while(x%i==0)k*=i,x/=i;
		ans+=crt(C(n,m,i,k),p,k);
		ans%=p;
	}
	if(x>1){
		ans+=crt(C(n,m,x,x),p,x);
		ans%=p;
	}
	return ans;
}
int main(){
	scanf("%lld%lld%d",&n,&m,&p);
	printf("%d\n",exlucas(n,m,p));
	return 0;
}

tarjan 求割点

#include<cstdio>
#define rep(i,a,b) for(int i=(a);i<=(b);++i) 
template<typename T>void rd(T&x){int f=0,c;while((c=getchar())<48||57<c)f^=!(c^45);x=(c&15);while(47<(c=getchar())&&c<58)x=x*10+(c&15);if(f)x=-x;}
template<typename T>T min(const T&x,const T&y){return x<y?x:y;}
const int N=20005,M=100005;
int n,m,ind,root,dfn[N],low[N];bool cut[N];
int lnk[N],pp;
struct ed{int nxt,v;}G[M<<1];
void ae(int u,int v){G[++pp]=(ed){lnk[u],v},lnk[u]=pp;}
void tarjan(int u){
	dfn[u]=low[u]=++ind;
	int tot=0;
	for(int i=lnk[u];i;i=G[i].nxt){
		int v=G[i].v;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(u!=root&&low[v]>=dfn[u]){
				++tot;
				if(u!=root||tot>1)cut[u]=1;
			}
		}else{
			low[u]=min(low[u],dfn[v]);
		}
	}
}
int main(){
	rd(n),rd(m);
	rep(i,1,m){
		int u,v;scanf("%d%d",&u,&v);
		ae(u,v),ae(v,u);
	}
	rep(i,1,n)if(!dfn[i])root=i,tarjan(i);
	int tot=0;rep(i,1,n)if(cut[i])++tot;printf("%d\n",tot);
	rep(i,1,n)if(cut[i])printf("%d ",i);
	return 0;
}

2-sat

//by xay5421 2449670833@qq.com
#include<set>
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define int long long
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()
#define debug(...) fprintf(stderr,__VA_ARGS__)
//#define debug(...) ((void)0)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;typedef unsigned long long ull;typedef std::pair<int,int> pii;
template<typename T>void rd(T&x){int f=0,c;while((c=getchar())<48||57<c)f^=!(c^45);x=(c&15);while(47<(c=getchar())&&c<58)x=x*10+(c&15);if(f)x=-x;}
template<typename T>inline void pt(T x){if(x<0)x=-x,putchar('-');if(x>9)pt(x/10);putchar(x%10+48);}
template<typename T>inline void pt(T x,int c){pt(x),putchar(c);}
template<typename T>inline T max(const T&x,const T&y){return x<y?y:x;}
template<typename T>inline T min(const T&x,const T&y){return x<y?x:y;}

const int N=2000005;

int n,m,nowid,nowc,ind,id[N][2],dfn[N],low[N],st[N],col[N];bool ins[N];

struct ed{int nxt,to;}G[N<<1];int lnk[N],pp;
void ae(int u,int v){G[++pp]=(ed){lnk[u],v},lnk[u]=pp;}

void tarjan(int u){
	dfn[u]=low[u]=++ind,ins[u]=1,st[++*st]=u;
	for(int i=lnk[u];i;i=G[i].nxt)
		if(!dfn[G[i].to]){
			tarjan(G[i].to);
			low[u]=min(low[u],low[G[i].to]);
		}else if(ins[G[i].to]){
			low[u]=min(low[u],dfn[G[i].to]);
		}
	if(dfn[u]==low[u]){
		++nowc;
		do{
			col[st[*st]]=nowc;
			ins[st[*st]]=0;
		}while(st[(*st)--]!=u);
	}
}

signed main(){
	rd(n),rd(m);
	rep(i,1,n)id[i][0]=++nowid;
	rep(i,1,n)id[i][1]=++nowid;
	rep(_,1,m){
		int i,a,j,b;
		rd(i),rd(a),rd(j),rd(b);		
		ae(id[i][a^1],id[j][b]);
		ae(id[j][b^1],id[i][a]);
	}
	rep(i,1,nowid)if(!dfn[i])
		tarjan(i);
	rep(i,1,n)
		if(col[id[i][0]]==col[id[i][1]]){
			puts("IMPOSSIBLE");
			return 0;
		}
	puts("POSSIBLE");
	rep(i,1,n)pt(col[id[i][0]]>col[id[i][1]],' ');
	return 0;
}

Link Cut Tree(LCT)

int get(int u){return ch[fa[u]][1]==u;}
int isroot(int u){return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;}
//void update(int u){mx[u]=max(val[u],max(mx[ch[u][0]],mx[ch[u][1]]));}
void pushdown(int u){
    if(rev[u])std::swap(ch[u][0],ch[u][1]),rev[ch[u][0]]^=1,rev[ch[u][1]]^=1,rev[u]^=1;
}
void rotate(int u){
    int p=fa[u],gp=fa[p],x=get(u);
    if(!isroot(p))ch[gp][get(p)]=u;fa[u]=gp;
    ch[p][x]=ch[u][x^1],fa[ch[u][x^1]]=p;
    ch[u][x^1]=p,fa[p]=u;
    update(p),update(u);
}
void splay(int u){
    st[*st=1]=u;
    for(int i=u;!isroot(i);i=fa[i])st[++*st]=fa[i];
    for(int i=*st;i>=1;--i)pushdown(st[i]);
    for(;!isroot(u);rotate(u))
        if(!isroot(fa[u]))
            rotate(get(u)==get(fa[u])?fa[u]:u);
}
void access(int u){
    for(int i=0;u;i=u,u=fa[u]){
        splay(u);
        ch[u][1]=i;
        update(u);
    }
}
void makeroot(int u){
    access(u);
    splay(u),rev[u]^=1; 
}
void link(int u,int v){
    makeroot(u),fa[u]=v;
}
int findroot(int u){
    access(u),splay(u);
    while(ch[u][0])u=ch[u][0];
    return splay(u),u;
}
void cut(int u,int v){
	makeroot(u),access(v),splay(v);
	if(ch[u][1]||fa[u]!=v)return;
	fa[u]=ch[v][0]=0;
}

hash,哈希

#include<ctime>
#include<cstdio>
#include<cassert>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,a[N],P[2];char s[N];
struct pii{
	int x,y;
	bool operator==(const pii&b)const{return x==b.x&&y==b.y;}
	pii operator+(const pii&b)const{return(pii){(x+b.x)%P[0],(y+b.y)%P[1]};}
	pii operator-(const pii&b)const{return(pii){(x-b.x+P[0])%P[0],(y-b.y+P[1])%P[1]};}
	pii operator*(const pii&b)const{return(pii){int(1LL*x*b.x%P[0]),int(1LL*y*b.y%P[1])};}
}h[2][N],pw[N],B;
pii get(int l,int r){
	int k1=lower_bound(a+1,a+1+m,l)-a-1,k2=upper_bound(a+1,a+1+m,r)-a-1;
	return h[l&1][k2]-h[l&1][k1]*pw[k2-k1];
}
int main(){
	srand(time(0));
	P[0]=998244853,P[1]=998244853+(rand()&0x7fff);
	B.x=3,B.y=rand()%10+3;
	pw[0]=(pii){1,1};
	scanf("%d%s",&n,s+1);
	for(int i=1;i<=n;++i)pw[i]=pw[i-1]*B;
	for(int i=1;i<=n;++i)if(s[i]=='0'){
		a[++m]=i;
		h[0][m]=h[0][m-1]*B+(pii){i%2+1,i%2+1};
		h[1][m]=h[1][m-1]*B+(pii){2-i%2,2-i%2};
	}
	int q;scanf("%d",&q);
	while(q--){
		int k1,k2,k3;
		scanf("%d%d%d",&k1,&k2,&k3);
		puts(get(k1,k1+k3-1)==get(k2,k2+k3-1)?"Yes":"No");
	}
	return 0;
}

回文自动机,PAM

struct PAM{
	int lst,cnt,tot[N],sum[N],len[N],fa[N],ch[N][26];
	char s[N];
	int newnode(int a,int b){return len[cnt]=a,fa[cnt]=b,cnt++;}
	PAM(){clear();}
	void clear(){
		rep(i,0,cnt-1){
			tot[i]=sum[i]=len[i]=fa[i]=0;
			memset(ch[i],0,sizeof(ch[i]));
		}
		lst=cnt=0;
		newnode(0,1),newnode(-1,0);
	}
	int get(int p,int n){for(;s[n-len[p]-1]!=s[n];p=fa[p]);return p;}
	void extend(int c,int pos){
		s[pos]=c+'a';
		int p=get(lst,pos);
		if(!ch[p][c]){
			ch[p][c]=newnode(len[p]+2,ch[get(fa[p],pos)][c]);
			int k1=ch[p][c];
			tot[k1]=tot[fa[k1]]+1;
			sum[k1]=(sum[fa[k1]]+len[k1])%P;
		}
		lst=ch[p][c];
	}
};

网络流,最大流,dinic,wxw

struct max_flow_t {
    struct edge_t {
        int u, v, next, cap, flow;
        edge_t () {}
        edge_t (int a, int b, int c, int d, int e) : u(a), v(b), next(c), cap(d), flow(e) {}
    };

    vector <edge_t> G;
    vector <int> head, nowhead, d;
    int n, s, t, tot;

    max_flow_t () { G.clear(); head.clear(); tot = 1; }
    max_flow_t (int nn) {
        n = nn; s = 0; t = n + 1;
        G.clear(); head.clear(); head.resize(n + 2, 0); tot = 1;
    }

    inline void addedge(int u, int v, int cap) {
        G.resize(tot + 3);
        G[++tot] = (edge_t) {u, v, head[u], cap, 0}, head[u] = tot;
        G[++tot] = (edge_t) {v, u, head[v], 0, 0}, head[v] = tot;
    }

    int bfs() {
        d.clear(); d.resize(n + 2, 0); d[s] = 1;
        queue <int> q; q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int i = head[u]; i; i = G[i].next) {
                int v = G[i].v;
                if (G[i].cap > G[i].flow && d[v] == 0) {
                    d[v] = d[u] + 1;
                    q.push(v);
                }
            }
        }
        return d[t];
    }

    int dfs(int u, int Flow) {
        if (u == t || !Flow) return Flow;
        int flow = 0, f;
        for (int &i = nowhead[u]; i; i = G[i].next) {
            int v = G[i].v;
            if (d[v] == d[u] + 1 && (f = dfs(v, min(Flow, G[i].cap - G[i].flow))) > 0) {
                G[i].flow += f; G[i ^ 1].flow -= f;
                flow += f; Flow -= f;
                if (!Flow) break;
            }
        }
        return flow;
    }

    int dinic() {
        int ans = 0;
        while (bfs()) {
            nowhead = head;
            ans += dfs(s, INF);
        }
        return ans;
    }
} M;

大数分解,PR

typedef long long LL;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
namespace PR{
	const int N=11,p[N]={2,3,5,7,11,13,17,19,23,29,61};
	LL add(LL k1,LL k2,LL P){(k1+=k2)>=P&&(k1-=P);return k1;}
	LL mul(LL k1,LL k2,LL P){
		LL k3=0;
		for(;k2;k2>>=1,k1=add(k1,k1,P))if(k2&1)k3=add(k3,k1,P);
		return k3;
	}
	LL fpow(LL k1,LL k2,LL P){
		k1%=P;
		LL k3=1;
		for(;k2;k2>>=1,k1=mul(k1,k1,P))if(k2&1)k3=mul(k3,k1,P);
		return k3;
	}
	bool chk(LL P,LL n){
		if(P%n==0||fpow(n,P-1,P)!=1)return 0;
		LL k=P-1;
		while(~k&1){
			k>>=1;
			LL t=fpow(n,k,P);
			if(t!=1&&t!=P-1)return 0;
			if(t==P-1)return 1;
		}
		return 1;
	}
	bool isp(LL n){
		for(int i=0;i<N;++i){
			if(n==p[i])return 1;
			if(!chk(n,p[i]))return 0;
		}
		return 1;
	}
	vector<LL>d;
	void report(LL x){
		d.push_back(x);
	}
	void work(LL n){
		if(n==1)return;
		if(isp(n)){
			report(n);
			return;
		}
		while(1){
			LL c=rng()%n,x=rng()%n,y=x,i=1,k=2;
			if(c==0||c==2)continue;
			do{
				LL d=__gcd(abs(x-y),n);
				if(d!=1&&d!=n){
					work(d),work(n/d);
					return;
				}
				if(++i==k)y=x,k<<=1;
				x=(mul(x,x,n)+c)%n;
			}while(x!=y);
		}
	}
	vector<pair<LL,int> >sol(LL n){
		d.clear();
		work(n);
		sort(d.begin(),d.end());
		vector<pair<LL,int> >res;
		for(int i=0,j;i<SZ(d);i=j){
			j=i+1;
			while(j<SZ(d)&&d[i]==d[j])++j;
			res.emplace_back(d[i],j-i);
		}
		return res;
	}
}
posted @ 2019-09-19 09:51  xay5421  阅读(727)  评论(0编辑  收藏  举报