zoukankan      html  css  js  c++  java
  • 模板合集

    神奇的模板...总之各种各样的模板整理...已经准备用我现在的码风重新打一遍了...

    高精度

    • 已重载运算符.没写FFT什么的...
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    const int B = 10;
    const int W = 1;
    
    struct Big{
    	vector<int> s;
    	void clear(){ s.clear(); }
    	
    	Big(LL num=0){ *this=num; }
    	Big operator = (LL x){
    		clear();
    		do{ s.push_back(x%B),x/=B; }while(x);
    		return *this;
    	}
    	Big operator = (const string &str){
    		clear();
    		int x,len=(str.length()-1)/W+1,l=str.length();
    		for(int i=0;i<len;i++){
    			int tt=l-i*W,st=max(0,tt-W);
    			sscanf(str.substr(st,tt-st).c_str(),"%d",&x);
    			s.push_back(x);
    		}return *this;
    	}
    };
    
    istream& operator >> (istream & in,Big &a){
    	string s;
    	if(!(in>>s)) return in;
    	a=s;return in;
    }
    
    ostream& operator << (ostream &out,const Big &a){
    	cout<<a.s.back();
    	for(int i=a.s.size()-2;~i;i--){
    		cout.width(W),cout.fill('0'),cout<<a.s[i];
    	}return out;
    }
    
    bool operator < (const Big &a,const Big &b){
    	int la=a.s.size(),lb=b.s.size();
    	if(la<lb) return 1;if(la>lb) return 0;
    	for(int i=la-1;~i;i--){
    		if(a.s[i]<b.s[i]) return 1;
    		if(a.s[i]>b.s[i]) return 0;
    	}return 0;
    }
    bool operator <= (const Big &a,const Big &b){ return !(b<a); }
    bool operator > (const Big &a,const Big &b){ return b<a; }
    bool operator >= (const Big &a,const Big &b){ return !(a<b); }
    bool operator == (const Big &a,const Big &b){ return !(a>b) && !(a<b); }
    bool operator != (const Big &a,const Big &b){ return a>b || a<b ; }
    
    
    Big operator + (const Big &a,const Big &b){
    	Big c;c.clear();
    	int lim=max(a.s.size(),b.s.size()),la=a.s.size(),lb=b.s.size(),i,g,x;
    	for(i=0,g=0;;i++){
    		if(g==0 && i>=lim) break;
    		x=g;if(i<la) x+=a.s[i];if(i<lb) x+=b.s[i];
    		c.s.push_back(x%B),g=x/B;
    	}i=c.s.size()-1;
    	while(c.s[i]==0 && i) c.s.pop_back(),i--;
    	return c;
    }
    Big operator - (const Big &a,const Big &b){
    	Big c;c.clear();
    	int i,g,x,la=a.s.size(),lb=b.s.size();
    	for(i=0,g=0;i<la;i++){
    		x=a.s[i]-g;
    		if(i<lb) x-=b.s[i];
    		if(x>=0) g=0;else g=1,x+=B;
    		c.s.push_back(x);
    	}i=c.s.size()-1;
    	while(c.s[i]==0 && i) c.s.pop_back(),i--;
    	return c;
    }
    Big operator * (const Big &a,const Big &b){
    	Big c;
    	int i,j,la=a.s.size(),lb=b.s.size(),lc=la+lb;
    	c.s.resize(lc,0);
    	for(i=0;i<la;i++) for(j=0;j<lb;j++) c.s[i+j]+=a.s[i]*b.s[j];
    	for(i=0;i<lc;i++) c.s[i+1]+=c.s[i]/B,c.s[i]%=B;
    	i=lc-1;while(c.s[i]==0 && i) c.s.pop_back(),i--;
    	return c;
    }
    Big operator / (const Big &a,const Big &b){
    	Big c,f=0;
    	int la=a.s.size(),i;
    	c.s.resize(la,0);
    	for(i=la-1;~i;i--){
    		f=f*B,f.s[0]=a.s[i];
    		int l=0,r=B,mid;
    		while(l<=r){
    			mid=(l+r)>>1;
    			if(mid*b > f) r=mid-1;
    			else l=mid+1;
    		}
    		f=f-r*b,c.s[i]=r;
    //		while(f>=b) f=f-b,c.s[i]++;
    	}i=la-1;while(c.s[i]==0 && i) c.s.pop_back(),i--;
    	return c;
    }
    Big operator % (const Big &a,const Big &b){
    	Big c=a-(a/b)*b;
    	return c;
    }
    Big operator ^ (Big &a,Big &b){
    	Big c=1;
    	for(;b!=0;b=b/2,a=a*a){
    		if(b.s[0] & 1) c=c*a;
    	}return c;
    }
    Big operator += (Big &a,const Big &b){ return a=a+b; }
    Big operator -= (Big &a,const Big &b){ return a=a-b; }
    Big operator *= (Big &a,const Big &b){ return a=a*b; }
    Big operator /= (Big &a,const Big &b){ return a=a/b; }
    Big operator %= (Big &a,const Big &b){ return a=a%b; }
    int main(){
    	Big A,B;
    	cin>>A>>B;
    	cout<<A/B;
    	return 0;
    }
    
    • FFT (O(nlogn))
    #include <bits/stdc++.h>
    using namespace std;
    
    #define mpr make_pair
    #define rr first
    #define ii second
    const int N = 5e5+50;
    const int M = 25;
    const double Pi = M_PI;
    typedef pair< double,double > Complex;
    
    Complex operator + (const Complex &a,const Complex &b) {
    	return mpr(a.rr+b.rr,a.ii+b.ii);
    }
    Complex operator - (const Complex &a,const Complex &b) {
    	return mpr(a.rr-b.rr,a.ii-b.ii);
    }
    Complex operator * (const Complex &a,const Complex &b) {
    	return mpr(a.rr*b.rr-a.ii*b.ii,a.rr*b.ii+a.ii*b.rr);
    }
    
    int n,m;
    Complex a[N],b[N],c[N];
    int ans[N],pow2[M];
    
    void init(int x) {
    	pow2[0]=1;
    	for(int i=1;i<M;i++) pow2[i]=pow2[i-1]<<1;
    	for(m=0,n=1;n<x;n<<=1,m++);
    	n<<=1,m++;
    }
    void Rev(Complex a[]) {
    	for(int i=0,j=0;i<n;i++) {
    		if(i>j) swap(a[i],a[j]);
    		for(int k=n>>1;(j^=k)<k;k>>=1);
    	}
    }
    void DFT(Complex y[],int r) {
    	Rev(y);
    	for(int i=2;i<=n;i<<=1) {
    		Complex wi=mpr(cos(2.0*Pi/i),r*sin(2.0*Pi/i));
    		for(int k=0;k<n;k+=i) {
    			Complex w=mpr(1.0,0.0);
    			for(int j=k;j<k+i/2;j++) {
    				Complex t1=y[j],t2=w*y[j+i/2];
    				y[j]=t1+t2,y[j+i/2]=t1-t2;
    				w=w*wi;
    			}
    		}
    	}if(r==-1) for(int i=0;i<n;i++) y[i].rr/=n;
    }
    void FFT(Complex a[],Complex b[],Complex c[]) {
    	DFT(a,1),DFT(b,1);
    	
    		for(int i=0;i<n;i++) c[i]=a[i]*b[i];
    	DFT(c,-1);
    }
    int main() {
    	string s1,s2;
    	cin>>s1>>s2;
    	reverse(s1.begin(),s1.end());
    	reverse(s2.begin(),s2.end());
    	init((int)max(s1.length(),s2.length()));
    	for(int i=0;i<(int)s1.length();i++) a[i]=mpr(s1[i]-'0',0);
    	for(int i=0;i<(int)s2.length();i++) b[i]=mpr(s2[i]-'0',0);
    	FFT(a,b,c);
    	for(int i=0;i<n;i++) ans[i]=c[i].rr+0.5;
    	for(int i=0;i<n;i++) ans[i+1]+=ans[i]/10,ans[i]%=10;
    	for(;!ans[n] && n;n--);
    	for(int i=n;~i;i--) putchar(ans[i]+'0');
    	return 0;
    }
    
    • FNT (O(nlogn))
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 5e5+50;
    const int p = (479 << 21) + 1;
    const int g = 3;
    
    int n;
    LL a[N],b[N],c[N];
    
    LL Pow(LL a,LL b,LL r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
    void init(int x) {
    	for(n=1;n<x;n<<=1);n<<=1;
    }
    void Rev(LL a[]) {
    	for(int i=0,j=0;i<n;i++) {
    		if(i>j) swap(a[i],a[j]);
    		for(int k=n>>1;(j^=k)<k;k>>=1);
    	}
    }
    void FNT(LL y[],int r) {
    	Rev(y);
    	for(int i=2;i<=n;i<<=1) {
    		LL wi=Pow(g,(p-1)/i);
    		if(r==-1) wi=Pow(wi,p-2);
    		for(int k=0;k<n;k+=i) {
    			LL w=1;
    			for(int j=k;j<k+i/2;j++) {
    				LL t1=y[j],t2=(w*y[j+i/2])%p;
    				y[j]=(t1+t2)%p,y[j+i/2]=(t1-t2+p)%p;
    				w=w*wi%p;
    			}
    		}
    	}if(r==-1) {
    		LL inv=Pow(n,p-2);
    		for(int i=0;i<n;i++) y[i]=y[i]*inv%p;
    	}
    }
    void FFT(LL a[],LL b[],LL c[]) {
    	FNT(a,1),FNT(b,1);
    	for(int i=0;i<n;i++) c[i]=a[i]*b[i]%p;
    	FNT(c,-1);
    }
    int main() {
    	string s1,s2;
    	cin>>s1>>s2;
    	reverse(s1.begin(),s1.end());reverse(s2.begin(),s2.end());
    	for(int i=0;i<s1.length();i++) a[i]=s1[i]-'0';
    	for(int i=0;i<s2.length();i++) b[i]=s2[i]-'0';
    	init(max(s1.length(),s2.length()));
    	FFT(a,b,c);
    	for(int i=0;i<n;i++) c[i+1]=(c[i+1]+c[i]/10),c[i]=c[i]%10;
    	int p=n;for(;!c[p] && p>0;p--);
    	for(;~p;p--) printf("%d",c[p]);
    	return 0;
    }
    

      

      

    优化

    • 读入优化
    char *ps=(char *)malloc(20000000);
    inline LL in(LL x=0){ for(;*ps>'9'||*ps<'0';ps++);
        for(;*ps>='0'&&*ps<='9';ps++) x=(x<<3)+(x<<1)+*ps-'0';return x; }
    
    fread(ps,1,20000000,stdin);
    • 输出优化
    inline void Out(LL x){
        int l=0;char ch[65];
        if(!x){ putchar('0');return; }
        if(x<0) putchar('-'),x=-x;
        while(x) ch[++l]=x%10+'0',x/=10;
        for(int i=l;i;i--) putchar(ch[i]);
    }

    计算几何

    • qwq
    #include <bits/stdc++.h>
    using namespace std;
     
    namespace CG {
    	typedef long double LD;
    	 
    	const LD Pi = M_PI;
    	const LD PI = 2 * acos(0.0);
    	const LD eps = 1e-18;
    	const LD oo = 1e15;
    	#define sqr(x) ((x)*(x))
    	 
    	int dcmp(LD x) { return fabs(x)<=eps?0:(x<0?-1:1); }
    	 
    	struct Point {
    		LD x,y;
    		Point(LD _x=0,LD _y=0) :x(_x),y(_y) {}
    		void out() { cout<<"("<<x<<","<<y<<")"; }
    	};
    	typedef Point Vector;
    	 
    	int cmpx(const Point &a,const Point &b) { return dcmp(a.x-b.x)==0?a.y<b.y:a.x<b.x; }
    	 
    	Vector operator + (const Vector &a,const Vector &b) { return Vector(a.x+b.x,a.y+b.y); }
    	Vector operator - (const Vector &a,const Vector &b) { return Vector(a.x-b.x,a.y-b.y); }
    	Vector operator * (const Vector &a,LD b) { return Vector(a.x*b,a.y*b); }
    	Vector operator / (const Vector &a,LD b) { return Vector(a.x/b,a.y/b); }
    	bool operator == (const Point &a,const Point &b) { return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
    	 
    	LD Dot(Vector a,Vector b) { return a.x*b.x+a.y*b.y; }
    	LD Cross(Vector a,Vector b) { return a.x*b.y-b.x*a.y; }
    	Vector Rot(Vector a,LD rd) { return Vector(a.x*cos(rd)-a.y*sin(rd),a.x*sin(rd)+a.y*cos(rd)); }
    	LD get_l(Vector a) { return sqrt(Dot(a,a)); }
    	LD get_d(Point a,Point b) { return sqrt(Dot(a-b,a-b)); }
    	LD get_a(Vector a) { return atan2(a.y,a.x); }
    	LD get_a(Vector a,Vector b) { return acos(Dot(a,b)/get_l(a)/get_l(b)); } 
    	LD get_s(Point a,Point b,Point c) { return Cross(b-a,c-a)/2.0; }
    	 
    	struct Line {
    		Point p;
    		Vector v;
    		LD ang;
    		Line(Point _p=Point(),Vector _v=Vector()):p(_p),v(_v) { ang=get_a(v); } 
    		LD get_l() { return sqrt(Dot(v,v)); } 
    		Point get_p(LD t) { return p+v*t; }
    		Point get_s() { return p; }
    		Point get_t() { return p+v; }
    		int chkleft(Point P) { return dcmp(Cross(v,P-p))>0; }
    	};
    	int cmpa(const Line &a,const Line &b) { return dcmp(a.ang-b.ang)==-1; }
    	Point get_l_l(Line a,Line b) {
    		Vector u=a.p-b.p;
    		LD t=Cross(b.v,u)/Cross(a.v,b.v);
    		return a.get_p(t);
    	}
    	typedef Line Hp;
    	int get_h_h(vector<Hp> &hs,vector<Point> &pt) {
    		sort(hs.begin(),hs.end(),cmpa);
    		vector<Point> p(hs.size());
    		vector<Hp> q(hs.size());
    		int h,t;
    		q[h=t=0]=hs[0];
    		for(int i=1;i<(int)hs.size();i++) {
    			while(h<t && !hs[i].chkleft(p[t-1])) t--;
    			while(h<t && !hs[i].chkleft(p[h])) h++;
    			q[++t]=hs[i];
    			if(fabs(Cross(q[t].v,q[t-1].v))<eps) {
    				t--;
    				if(q[t].chkleft(hs[i].p)) q[t]=hs[i];
    			}
    			if(h<t) p[t-1]=get_l_l(q[t-1],q[t]);
    		}
    		while(h<t && !q[h].chkleft(p[t-1])) t--;
    		p[t]=get_l_l(q[h],q[t]);
    		for(int i=h;i<=t;i++) pt.push_back(p[i]);
    		return t-h+1;
    	}
    	
    	struct Circle {
    		Point c;
    		LD r;
    		Point get_p(LD t) { return c+Point(cos(t)*r,sin(t)*r); }
    		LD get_rd(Point a,Point b) { return get_a(a-c,b-c); }
    		LD get_l(LD rd) { return r*rd; } 
    	};
    	 
    	int get_c_l(Line L,Circle C,vector<Point> &res) {
    		LD a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;
    		LD e=sqr(a)+sqr(c),f=2.0*(a*b+c*d),g=sqr(b)+sqr(d)-sqr(C.r);
    		LD dt=f*f-4*e*g;
    		if(dcmp(dt)<0) return 0;
    		if(dcmp(dt)==0) return res.push_back(L.get_p(-f/(2.0*e))),1;
    		LD x1=(-f-sqrt(dt))/(2.0*e),x2=(-f+sqrt(dt))/(2.0*e);
    		if(x1>x2) swap(x1,x2);
    		res.push_back(L.get_p(x1)),res.push_back(L.get_p(x2));return 2;
    	}
    	int get_c_c(Circle A,Circle B,vector<Point> &res) {
    		LD d=get_l(A.c-B.c);
    		if(dcmp(d)==0) return dcmp(A.r-B.r)==0?-1:0;
    		if(dcmp(A.r+B.r-d)<0) return 0;
    		if(dcmp(fabs(A.r-B.r)-d)>0) return 0;
    		 
    		LD a=get_a(B.c-A.c);
    		LD rd=acos((sqr(A.r)+sqr(d)-sqr(B.r))/(2.0*A.r*d));
    		 
    		Point p1,p2;
    		p1=A.get_p(a+rd),p2=A.get_p(a-rd);
    		 
    		res.push_back(p1);
    		if(p1==p2) return 1;
    		res.push_back(p2);
    		return 2;
    	}
    	 
    	/*---io---*/   
    	ostream & operator << (ostream &os,const Point &p) { os<<p.x<<" "<<p.y;return os; }
    	istream & operator >> (istream &is,Point &p) { is>>p.x>>p.y;return is; }
    	ostream & operator << (ostream &os,const Circle &C) { os<<C.c<<" "<<C.r;return os; }
    	istream & operator >> (istream &is,Circle &C) { is>>C.c>>C.r;return is; }
    };
    int main() {
    	
    }
    

      

    图论

    • Tarjan-割点 (O(m))
    #include<cstdio>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    const int N = 100005;
    #define debug(a) cout<<#a<<"="<<a<<" "
    
    int n,m,cnt,ans;
    vector<int> g[N];
    int b[N],out[N],du[N];
    int dfsn[N],low[N];
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void Tarjan(int u,int fa){
    	dfsn[u]=low[u]=++cnt;int c=0;
    	for(int i=0,v;i<du[u];i++) if((v=g[u][i])!=fa){
    		if(!dfsn[v]){
    			Tarjan(v,u),low[u]=min(low[u],low[v]),c++;
    			if(fa>0&&dfsn[u]<=low[v]) b[u]=1;
    		}else low[u]=min(low[u],dfsn[v]);
    	}if(fa==0&&c>1) b[u]=1;
    }
    int main(){
    	n=in(),m=in();
    	for(int i=1,u,v;i<=m;i++) u=in(),v=in(),du[u]++,du[v]++,g[u].push_back(v),g[v].push_back(u);
    	for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i,0);
    	for(int i=1;i<=n;i++) if(b[i]) out[++ans]=i;
    	printf("%d
    ",ans);
    	for(int i=1;i<=ans;i++) printf("%d ",out[i]);putchar('
    ');
    	return 0;
    }
    • Tarjan-割边(桥) (O(m))
    #include<cstdio>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    const int N = 100005;
    #define mpr(a,b) make_pair(a,b)
    
    int n,m,cnt,ans;
    int iscut[N],e[N];
    int dfsn[N],low[N];
    struct Edge{ int fr,to,id; }edge[N];
    vector<Edge> g[N];
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    inline void Add_Edge(int u,int v,int id){
    	edge[id]=(Edge){ u,v,id };
    	g[u].push_back((Edge){ u,v,id });
    	g[v].push_back((Edge){ v,u,id });
    }
    void Tarjan(int u,int fa){
    	dfsn[u]=low[u]=++cnt;
    	for(int i=0,lim=g[u].size(),v;i<lim;i++) if((v=g[u][i].to)!=fa){
    		if(!dfsn[v]){
    			Tarjan(v,u);
    			if(low[v]>dfsn[u]) iscut[g[u][i].id]=1;
    			low[u]=min(low[u],low[v]);
    		}else low[u]=min(low[u],dfsn[v]);
    	}
    }
    int main(){
    	n=in(),m=in();
    	for(int i=1,u,v;i<=m;i++) u=in(),v=in(),Add_Edge(u,v,i);
    	for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i,0);
    	for(int i=1;i<=m;i++) if(iscut[i]) e[++ans]=i;
    	printf("%d
    ",ans);
    	for(int i=1;i<=ans;i++) printf("%d
    ",e[i]);
    	return 0;
    }
    
    • Tarjan-强连通分量+缩点. (O(m))
    #include<cstdio>
    #include<stack>
    #include<vector>
    #include<iostream>
    using namespace std;
       
    const int N = 10005;
    #define debug(a) cout<<#a<<"="<<a<<" "
    #define ct cout<<endl
    #define _ct cout<<"----------"<<endl
       
    int n,m,cnt,bcnt;
    int dfsn[N],low[N],ins[N],b[N],sz[N];
    vector<int> g[N];
    vector<int> h[N];
    stack<int> stk;
    struct Edge{ int fr,to; }edge[N*5];
       
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void Tarjan(int u){
        dfsn[u]=low[u]=++cnt,ins[u]=1,stk.push(u);
        for(int i=0,lim=g[u].size(),v;i<lim;i++){
            v=g[u][i];
            if(!dfsn[v]){ Tarjan(v),low[u]=min(low[u],low[v]); }
            else if(ins[v]) low[u]=min(low[u],dfsn[v]);
        }if(dfsn[u]==low[u]){
            ++bcnt;int v;
            for(;;){ v=stk.top(),stk.pop(),ins[v]=0,b[v]=bcnt,sz[bcnt]++;if(u==v) break; }
        }
    }
    int main(){
    //  freopen("in.in","r",stdin);
        n=in(),m=in();
        for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u].push_back(v),edge[i]=(Edge){ u,v };
        for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i);
    //  _ct;debug(bcnt),ct;
        for(int i=1,u,v;i<=m;i++){
            u=edge[i].fr,v=edge[i].to;
    //      debug(u),debug(v),ct;
    //      debug(b[u]),debug(b[v]),ct;
            if(b[u]!=b[v]) h[b[u]].push_back(b[v]);
        }return 0;
    }
    
    • LCA-倍增 (O(nlogn+mlogn))
    #include<cstdio>
    #include<utility>
    #include<vector>
    #include<iostream>
    using namespace std;
     
    #define mpr make_pair
    #define debug(a) cout<<#a<<"="<<a<<" "
    typedef pair< int,int > pr;
    const int N = 50005;
    const int M = 31;
     
    int n,m,k;
    vector<pr> h[N];
    int pow2[M],d[N];
    int f[N][M],g[N][M];
     
    inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void DFS(int u,int fa,int dep){
        d[u]=dep;
        for(int i=0,v;i<h[u].size();i++) if((v=h[u][i].first)!=fa){
            DFS(v,u,dep+1),f[v][0]=u,g[v][0]=h[u][i].second;
        }
    }
    void work(){
        pow2[0]=1;for(int i=1;i<M;i++) pow2[i]=pow2[i-1]<<1;
        for(int j=1;j<M;j++) for(int i=0;i<n;i++) f[i][j]=f[f[i][j-1]][j-1],g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1];
    }
    int Dis(int u,int v){
        if(d[u]<d[v]) swap(u,v);
        int l=d[u]-d[v],res=0;
        if(l) for(int i=0;i<M;i++) if(l&pow2[i]) res+=g[u][i],u=f[u][i];
        if(u==v) return res;
        for(int i=M-1;~i;--i){
            if(f[u][i]!=f[v][i]) res+=g[u][i]+g[v][i],u=f[u][i],v=f[v][i];
        }return g[u][0]+g[v][0]+res;
    }
    int main(){
        n=in();
        for(int i=1,u,v,w;i<n;i++) u=in(),v=in(),w=in(),h[u].push_back(mpr(v,w)),h[v].push_back(mpr(u,w));
        DFS(0,0,1);
        work();
        for(k=in();k--;){
            int u=in(),v=in();
            printf("%d
    ",Dis(u,v));
        }return 0;
    }
    
    • LCA-ST表 (O(nlogn+m))
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<utility>
    #include<vector>
    #include<iostream>
    using namespace std;
     
    #define debug(a) cout<<#a<<"="<<a<<" "
    #define mpr make_pair
    typedef pair< int,int > pr;
    const int N = 200005;
    const int M = 25;
     
    int n,m,cnt;
    vector< pr > g[N];
    int pow2[M],dfs[N],d[N],val[N],pos[N],lg2[N];
    int f[N][M];
     
     
    inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void DFS(int u,int fa,int dep,int value){
        dfs[++m]=u,d[u]=dep,val[u]=value,pos[u]=m,f[m][0]=u;
        for(int i=0,v;i<g[u].size();i++) if((v=g[u][i].first)!=fa) DFS(v,u,dep+1,value+g[u][i].second),dfs[++m]=u,f[m][0]=u;
    }
    void init(){
        pow2[0]=1;for(int i=1;i<M;i++) pow2[i]=pow2[i-1]<<1;
        lg2[0]=-1;for(int i=1;i<=m;i++) lg2[i]=lg2[i>>1]+1;
        for(int j=1;j<M;j++) for(int i=1;i<=m;i++) if(i+pow2[j]-1<=m){
            int u=f[i][j-1],v=f[i+pow2[j-1]][j-1];
            if(d[u]<d[v]) f[i][j]=u;else f[i][j]=v;
        }
    }
    int Dis(int u,int v,int lca=0){
        if(pos[u]<pos[v]) swap(u,v);
        int lg=lg2[pos[u]-pos[v]+1];
        if(d[f[pos[v]][lg]]<d[f[pos[u]-pow2[lg]+1][lg]]) lca=f[pos[v]][lg];else lca=f[pos[u]-pow2[lg]+1][lg];
        return val[u]+val[v]-2*val[lca];
    }
    int main(){
        memset(d,0x3f,sizeof(d));
        n=in();
        for(int i=1,u,v,w;i<n;i++) u=in(),v=in(),w=in(),g[u].push_back(mpr(v,w)),g[v].push_back(mpr(u,w));
        DFS(0,0,1,0),init();
        for(int k=in(),u,v;k--;){
            u=in(),v=in();
            printf("%d
    ",Dis(u,v));
        }return 0;
    }
    • 网络流-ISAP  (O(V^{2}E))
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<iostream>
    using namespace std;
    
    const int INF = 0x7fffffff;
    const int N = 505;
    const int M = 805;
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    struct NetWork{
    	int n,m,s,t;
    	struct Edge{ int fr,to,flow; }edge[M<<1];int cnte;
    	vector<int> g[N];int flow;
    	int num[N],cur[N],d[N],p[N];bool v[N];
    
    
    	void Add_Edge(int fr,int to,int fl){
    		edge[cnte++]=(Edge){ fr,to,fl },edge[cnte++]=(Edge){ to,fr,0 };
    		g[fr].push_back(cnte-2),g[to].push_back(cnte-1);
    	}
    	int Add_Flow(){
    		int a=INF;
    		for(int x=t;x!=s;x=edge[p[x]].fr) a=min(a,edge[p[x]].flow);
    		for(int x=t;x!=s;x=edge[p[x]].fr) edge[p[x]].flow-=a,edge[p[x]^1].flow+=a;
    		return a;
    	}
    	void BFS(){
    		for(int i=1;i<=n;i++) d[i]=n;
    		memset(v,0,sizeof(v));
    		queue<int> q;q.push(t),v[t]=1,d[t]=0;
    		for(int x;!q.empty();){
    			x=q.front(),q.pop();
    			for(int i=0,lim=g[x].size();i<lim;i++){
    				Edge &e=edge[g[x][i]];
    				Edge &u=edge[g[x][i]^1];
    				if(!v[e.to]&&u.flow) d[e.to]=d[x]+1,v[e.to]=1,q.push(e.to);
    			}
    		}
    	}
    	int ISAP(){
    		BFS();int flow=0;
    		memset(num,0,sizeof(num)),memset(cur,0,sizeof(cur));
    		for(int i=1;i<=n;i++) num[d[i]]++;
    		for(int x=s,ok;d[s]<n;){
    			if(x==t) flow+=Add_Flow(),x=s;ok=0;
    			for(int &i=cur[x],lim=g[x].size();i<lim;i++){
    				Edge &e=edge[g[x][i]];
    				if(e.flow&&d[x]==d[e.to]+1){
    					ok=1,p[e.to]=g[x][i],x=e.to;break;
    				}
    			}
    			if(!ok){
    				int tmp=n-1;
    				for(int i=0,lim=g[x].size();i<lim;i++) tmp=min(tmp,d[edge[g[x][i]].to]);
    				if(!(--num[d[x]])) break;num[d[x]=m+1]++,cur[x]=0;
    				if(x!=s) x=edge[p[x]].fr;
    			}
    		}return flow;
    	}
    }isap;
    int main(){ return 0; }
    • 网络流-Dinic  (O(VE^{2}))/二分图(O(sqrt{V}E))
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    const int N = 505;
    const int INF = 0x7fffffff;
    
    int T,n,m,cnt,ans;
    struct NetWork{
    	int n,m,s,t,flow;
    	struct Edge{ int fr,to,flow; };
    	vector<Edge> edge;vector<int> g[N];
    	int cur[N],d[N],p[N];
    	
    	void Add_Edge(int fr,int to,int flow){
    		edge.push_back((Edge){ fr,to,flow });
    		edge.push_back((Edge){ to,fr,0 });
    		m=edge.size();
    		g[fr].push_back(m-2),g[to].push_back(m-1);
    	}
    	int BFS(){
    		memset(d,-1,sizeof(d));
    		queue<int> q;q.push(s),d[s]=0;
    		for(int x;!q.empty();){
    			x=q.front(),q.pop();
    			for(int i=0,lim=g[x].size();i<lim;i++){
    				Edge &e=edge[g[x][i]];
    				if(e.flow&&d[e.to]==-1) d[e.to]=d[x]+1,q.push(e.to);
    			}
    		}return d[t]!=-1;
    	}
    	int Dinic(){
    		flow=0;
    		for(int x,k;BFS();){
    			memset(cur,0,sizeof(cur));x=s,k=0;
    			for(int ok;;){
    				if(x==t){
    					int mine=-1,minf=0x7fffffff;
    					for(int i=0;i<k;i++) if(edge[p[i]].flow<minf) minf=edge[p[i]].flow,mine=i;
    					for(int i=0;i<k;i++) edge[p[i]].flow-=minf,edge[p[i]^1].flow+=minf;
    					x=edge[p[mine]].fr,k=mine,flow+=minf;
    				}ok=0;
    				for(int &i=cur[x],lim=g[x].size();i<lim;i++){
    					Edge &e=edge[g[x][i]];
    					if(e.flow>0&&d[x]+1==d[e.to]){
    						p[k++]=g[x][i],x=e.to,ok=1;break;
    					}
    				}
    				if(!ok){ if(!k) break;d[x]=-1,x=edge[p[--k]].fr; }
    			}
    		}return flow;
    	}
    }dinic;
    int main(){ return 0; }
    
    • 最小生成树计数Matrix-Tree定理 (O(n^3))
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const double eps = 1e-8;
    const int N = 105;
    #define _0(x) ((x>0?x:-x)+eps>0)
    
    int n,m;
    int g[N][N],d[N];
    double a[N][N];
    
    double det(int n){
    	double res=1;int swpt=0;
    	for(int i=0,j,k;i<n;i++){
    		if(!_0(a[i][i])){
    			for(j=i+1;j<n;j++) if(_0(a[j][i])) break;
    			if(j>=n) return 0;
    			for(k=i;k<n;k++) swap(a[i][k],a[j][k]);
    			swpt++;
    		}res*=a[i][i];
    		
    //		for(j=i+1;j<n;j++) a[i][j]/=a[i][i];
    		for(j=i+1;j<n;j++) for(k=i+1;k<n;k++) a[j][k]-=a[j][i]*a[i][k]/a[i][i];
    	if(swpt&1) return -res;return res;
    }
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    int main(){
    	for(int T=in();T--;){
    		n=in(),m=in();memset(a,0,sizeof(a)),memset(g,0,sizeof(g)),memset(d,0,sizeof(d));
    		for(int i=1,u,v;i<=m;i++) u=in()-1,v=in()-1,g[u][v]=g[v][u]=1,d[u]++,d[v]++;
    		for(int i=0;i<n;i++) a[i][i]=d[i];
    		for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(g[i][j]) a[i][j]-=1;
    //		for(int i=0;i<n;i++) for(int j=0;j<n;j++) printf("%.0lf%c",a[i][j]," 
    "[j==n-1]);
    		printf("%.0lf
    ",det(n-1));
    //		for(int i=0;i<n;i++) for(int j=0;j<n;j++) printf("%.0lf%c",a[i][j]," 
    "[j==n-1]);
    	}return 0;
    }
    
    • 曼哈顿最小生成树 (O(n logn))
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<utility>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    using namespace std;
     
    #define mpr(a,b) make_pair(a,b)
    const int N = 50005;
     
    int n,ans;
    struct seat{ int x,y,id; }a[N],b[N];
    bool operator < (const seat &a,const seat &b){ return a.x==b.x?a.y>b.y:a.x>b.x; }
    int d[N<<1],id[N<<1],cnt,ys[N];
    struct Edge{ int u,v,w; };
    bool operator < (const Edge &a,const Edge &b){ return a.w>b.w; }
    priority_queue<Edge> q;
    int f[N];
     
    inline int in(int x=0,char ch=getchar(),int v=1){
        while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();if(ch=='-') v=-1,ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*v; }
    //int cmpx(const seat &a,const seat &b){ return a.x==b.x?a.x<b.x:a.y<b.y; }
    //int cmpxy(const seat &a,const seat &b){ return a.y-a.x<b.y-b.x; }
    inline int abs(int x){ return x<0?-x:x; }
    int find(int x){ return f[x]==x?x:f[x]=find(f[x]); }
    void Add_Edge(int u,int v){
        int dis=abs(a[u].x-a[v].x)+abs(a[u].y-a[v].y);
        q.push((Edge){ u,v,dis });
    }
    void Add(int x,int v,int pos){
        for(;x;x-=x&-x) if(d[x]>v) d[x]=v,id[x]=pos;
    }
    int Query(int x){
        int minv=0x7f7f7f7f,pos=-1;
        for(;x<=cnt;x+=x&-x) if(d[x]<minv) minv=d[x],pos=id[x];
        return pos;
    }
    void out(seat a){ cout<<a.x<<" "<<a.y<<" "<<a.id<<endl<<"***************
    "; }
    void Build(){
    /*        Part1 x1>x0&&y1-x1>y0-x0     dis=(x1+y1)-(x0+y0)         */
        memset(d,0x7f,sizeof(d)),memset(id,-1,sizeof(id)),memset(ys,0,sizeof(ys));cnt=0;
        for(int i=1;i<=n;i++) b[i]=a[i];
    //  for(int i=1;i<=n;i++) out(a[i]);
        sort(b+1,b+n+1);
    //  for(int i=1;i<=n;i++) out(b[i]);
        for(int i=1;i<=n;i++) ys[i]=b[i].y-b[i].x;
        sort(ys+1,ys+n+1);
        cnt=unique(ys+1,ys+n+1)-ys-1;
         
    //  cout<<cnt<<endl;
    //  for(int i=1;i<=cnt;i++) cout<<ys[i]<<" ";cout<<endl;
         
        for(int i=1;i<=n;i++){
            int x=lower_bound(ys+1,ys+cnt+1,b[i].y-b[i].x)-ys;
            int pos=Query(x);
            if(~pos) Add_Edge(b[i].id,pos);
    //      cout<<b[i].id<<"-->"<<pos<<endl;
            Add(x,b[i].x+b[i].y,b[i].id);
        }
    /*        Part2 swap(x,y)                                            */
        memset(d,0x7f,sizeof(d)),memset(id,-1,sizeof(id)),memset(ys,0,sizeof(ys));cnt=0;
        for(int i=1;i<=n;i++) b[i].y=a[i].x,b[i].x=a[i].y,b[i].id=a[i].id;
        sort(b+1,b+n+1);
    //  for(int i=1;i<=n;i++) out(b[i]);
        for(int i=1;i<=n;i++) ys[i]=b[i].y-b[i].x;
        sort(ys+1,ys+n+1);
        cnt=unique(ys+1,ys+n+1)-ys-1;
         
    //  cout<<cnt<<endl;
    //  for(int i=1;i<=cnt;i++) cout<<ys[i]<<" ";cout<<endl;
         
        for(int i=1;i<=n;i++){
            int x=lower_bound(ys+1,ys+cnt+1,b[i].y-b[i].x)-ys;
            int pos=Query(x);
            if(~pos) Add_Edge(b[i].id,pos);
    //      cout<<b[i].id<<"-->"<<pos<<endl;
            Add(x,b[i].x+b[i].y,b[i].id);
        }
     
    /*        Part3 y=-y                                                 */
        memset(d,0x7f,sizeof(d)),memset(id,-1,sizeof(id)),memset(ys,0,sizeof(ys));cnt=0;
        for(int i=1;i<=n;i++) b[i]=a[i],b[i].y=-b[i].y;
        sort(b+1,b+n+1);
    //  for(int i=1;i<=n;i++) out(b[i]);
        for(int i=1;i<=n;i++) ys[i]=b[i].y-b[i].x;
        sort(ys+1,ys+n+1);
        cnt=unique(ys+1,ys+n+1)-ys-1;
         
    //  cout<<cnt<<endl;
    //  for(int i=1;i<=cnt;i++) cout<<ys[i]<<" ";cout<<endl;
         
        for(int i=1;i<=n;i++){
            int x=lower_bound(ys+1,ys+cnt+1,b[i].y-b[i].x)-ys;
            int pos=Query(x);
            if(~pos) Add_Edge(b[i].id,pos);
    //      cout<<b[i].id<<"-->"<<pos<<endl;
            Add(x,b[i].x+b[i].y,b[i].id);
        }
     
    /*        Part4 swap(x,y) y=-y                                       */
        memset(d,0x7f,sizeof(d)),memset(id,-1,sizeof(id)),memset(ys,0,sizeof(ys));cnt=0;
        for(int i=1;i<=n;i++) b[i].x=-a[i].y,b[i].y=a[i].x,b[i].id=a[i].id;
        sort(b+1,b+n+1);
    //  for(int i=1;i<=n;i++) out(b[i]);
        for(int i=1;i<=n;i++) ys[i]=b[i].y-b[i].x;
        sort(ys+1,ys+n+1);
        cnt=unique(ys+1,ys+n+1)-ys-1;
         
    //  cout<<cnt<<endl;
    //  for(int i=1;i<=cnt;i++) cout<<ys[i]<<" ";cout<<endl;
         
        for(int i=1;i<=n;i++){
            int x=lower_bound(ys+1,ys+cnt+1,b[i].y-b[i].x)-ys;
            int pos=Query(x);
            if(~pos) Add_Edge(b[i].id,pos);
    //      cout<<b[i].id<<"-->"<<pos<<endl;
            Add(x,b[i].x+b[i].y,b[i].id);
        }
    /*         MST                                                       */
        for(int i=1;i<=n;i++) f[i]=i;
        for(int k=1;!q.empty();){
            Edge e=q.top();q.pop();
            int u=e.u,v=e.v;
            int f1=find(u),f2=find(v);
            if(f1!=f2) k++,f[f2]=f1,ans+=e.w;
            if(k>=n) break;
        }cout<<ans<<endl;
    }
    int main(){
    //  freopen("in.in","r",stdin);
    //  freopen("out.out","w",stdout);
        n=in();for(int i=1;i<=n;i++) a[i].x=in(),a[i].y=in(),a[i].id=i;
        Build();
        return 0;
    }
    
    • 朱刘算法/最小树形图 (O(nm))
    #include <bits/stdc++.h>
    using namespace std;
      
    inline int in(int x=0,char ch=getchar()) { while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
      
    const int N = 55;
    const int M = N*N+50;
      
    struct Edge { int fr,to;double v; };
    Edge edge[M];
      
    int n,m,rt;
    int b[N];
    double mic[N];
    double miv[N];
    int pre[N],vis[N],id[N];
      
    void AddEdge(int fr,int to,double v) { edge[++m]=(Edge){ fr,to,v }; }
      
    double Solve(int n) {
        double res=0;
        for(int cnt,tmp;;) {
            for(int i=1;i<=n;i++) miv[i]=1e9,pre[i]=0;
            for(int i=1;i<=m;i++) {
                Edge &e=edge[i];
                if(e.v<miv[e.to]) miv[e.to]=e.v,pre[e.to]=e.fr;
            }
            for(int i=1;i<=n;i++) if(pre[i]) res+=miv[i];
            memset(vis,0,sizeof(vis));
            memset(id,0,sizeof(id));
            vis[0]=tmp=1,cnt=0;
            for(int i=1;i<=n;i++) if(!vis[i]) {
                ++tmp;int u=i;
                for(;!vis[u];u=pre[u]) vis[u]=tmp;
                if(vis[u]==tmp) {
                    ++cnt;
                    for(;!id[u];u=pre[u]) id[u]=cnt;
                }
            }
            if(!cnt) break;
            for(int i=1;i<=n;i++) if(!id[i]) id[i]=++cnt;
            int mm=m;m=0;
            for(int i=1;i<=mm;i++) {
                Edge &e=edge[i];
                if(id[e.fr]!=id[e.to]) AddEdge(id[e.fr],id[e.to],e.v-miv[e.to]);
            }
            n=cnt;
        }return res;
    }
      
    int main() {
        n=in(),rt=n+1;
        for(int i=1;i<=n;i++) {
            double x;scanf("%lf",&x);
            mic[i]=x;
            b[i]=in();
            if(b[i]) AddEdge(rt,i,x);
        }
        for(int k=in();k--;) {
            int x=in(),y=in();
            double z;scanf("%lf",&z);
            if(b[x] && b[y]) {
                AddEdge(x,y,z);
                mic[y]=min(mic[y],z);
            }
        }
        double ans=Solve(n+1);
    //  cout<<ans<<endl;
    //  for(int i=1;i<=n;i++) cout<<mic[i]<<" ";cout<<endl;
        for(int i=1;i<=n;i++) if(b[i]) ans+=(b[i]-1)*mic[i];
        printf("%.2lf
    ",ans);
        return 0;
    }
    

      

    数学

    • 快速幂 (O(logn)) 快速乘 (O(1))
    inline LL Mul(LL a,LL b,LL p){
        if(p<=1000000000) return a*b%p;
        return (a*b-(LL)(a/(long double)p*b+1e-3)*p+p)%p;
    //  for(;b;b>>=1,a=(a+a)%p) if(b&1) res=(res+a)%p;return res;
    }
    inline LL Pow(LL a,LL b,LL p,LL res=1){ for(;b;b>>=1,a=Mul(a,a,p)) if(b&1) res=Mul(res,a,p);return res; }
    
    • (varphi(n)) (O(sqrt{n}))

    inline LL GetPhi(LL p){
        LL res=p,m=sqrt(p)+0.5;
        for(int i=2;i<=m;i++) if(p%i==0){
            res=res/i*(i-1);
            while(p%i==0) p/=i;
        }
        if(p>1) res=res/p*(p-1);return res;
    }
    • 线性筛 (mu) (O(n))
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    using namespace std;
    
    const int N = 1000005;
    
    int mu[N],pr[N],cnt;
    bool b[N];
    void Pre(){
    	mu[1]=1;
    	for(int i=2;i<=N;i++){
    		if(!b[i]) mu[i]=-1,pr[++cnt]=i;
    		for(int j=1;j<=cnt&&pr[j]*i<=N;j++){
    			b[i*pr[j]]=1;
    			if(i%pr[j]) mu[i*pr[j]]=-mu[i];
    			else break;
    		}
    	}
    //	for(int i=1;i<=10;i++) cout<<mu[i]<<" ";cout<<endl;
    }
    int main(){ Pre();return 0; }
    • 矩阵乘法和矩阵快速幂 (O(n^3) O(n^3 logn))
    #include<cstdio>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    typedef vector<LL> Vec;
    typedef vector<Vec> Mat;
    const LL p = 10000000007LL;
    
    Mat operator * (const Mat &A,const Mat &B){
        Mat C(A.size(),Vec(B[0].size()));
        for(int i=0;i<A.size();i++) for(int j=0;j<B[0].size();j++) for(int k=0;k<A[0].size();k++)
            C[i][j]=(C[i][j]+A[i][k]*B[k][j])%p;
        return C;
    }
    Mat operator ^ (Mat A,LL b){
        Mat res(A.size(),Vec(A[0].size()));
        for(int i=0;i<A.size();i++) for(int j=0;j<A[0].size();j++) res[i][j]=(i==j)?1:0;
        for(;b;b>>=1,A=A*A) if(b&1) res=res*A;
        return res;
    }
    int main(){ return 0; }
    
    • 扩展欧几里得 (O(logn))
    LL Exgcd(LL a,LL b,LL &x,LL &y){
    	if(!b){ x=1,y=0;return a; }
    	LL r=Exgcd(b,a%b,x,y);LL t=x;
    	x=y,y=t-(a/b)*y;return r;
    }
    
    • 中国剩余定理 (O(nlogn))
    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    const int N = 1005;
    
    int n;
    LL m[N],a[N];
    
    LL Exgcd(LL a,LL b,LL &x,LL &y){
    	if(!b){ x=1,y=0;return a; }
    	LL r=Exgcd(b,a%b,x,y);LL t=x;
    	x=y,y=t-(a/b)*y;return r;
    }
    LL Solve(){
    	LL M=m[1],MM,res=0,x,y;
    	for(int i=2;i<=n;i++) M*=m[i];
    	for(int i=1;i<=n;i++){
    		MM=M/m[i];
    		Exgcd(MM,m[i],x,y);
    		res=(res+MM*x*a[i])%M;
    	}return res;
    }
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>m[i]>>a[i];
    	Solve();
    	return 0;
    }
    • 求解模线性方程组 (O(nlogn))
    #include<cstdio>
    #include<utility>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    #define mpr make_pair
    const int N = 1005;
    
    LL n,a1,a2,b1,b2;
    pair< LL,LL > m[N];
    
    inline LL in(LL x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
    	while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    LL Exgcd(LL a,LL b,LL &x,LL &y){
    	if(!b){ x=1,y=0;return a; }
    	LL r=Exgcd(b,a%b,x,y);LL t=x;
    	x=y,y=t-(a/b)*y;return r;
    }
    int Solve(){
    	LL x,y,d=Exgcd(a1,a2,x,y);
    	if((b2-b1)%d) return 0;
    	Exgcd(a1/d,a2/d,x,y),x*=(b2-b1)/d,x=(x%(a2/d)+a2/d)%(a2/d);
    	b1=a1*x+b1,a1=a1/d*a2,b1=(b1%a1+a1)%a1;
    	return 1;
    }
    int main(){
    	n=in();
    	for(LL i=1,u,v;i<=n;i++) u=in(),v=in(),m[i]=mpr(u,v);
    	a1=m[1].first,b1=m[1].second;
    	for(int i=2;i<=n;i++){
    		a2=m[i].first,b2=m[i].second;
    		if(!Solve()) return puts("-1"),0;
    	}return printf("%lld
    ",b1),0;
    }
    

      

    字符串

    • 后缀数组 (O(nlogn))
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 200050;
    
    int n,m=26;
    char s[N];
    int a[N];
    
    namespace SuffixArray {
    	int s1[N],s2[N],sa[N],rk[N],ht[N],c[N];
    	
    	void get_sa(int a[],int n=::n,int m=::m) {
    		int *x=s1,*y=s2;
    		for(int i=1;i<=n;i++) c[x[i]=a[i]]++;
    		for(int i=1;i<=m;i++) c[i]+=c[i-1];
    		for(int i=n;i;--i) sa[c[a[i]]--]=i;
    		for(int k=1,p=0;k<n;k<<=1,p=0) {
    			for(int i=n-k+1;i<=n;i++) y[++p]=i;
    			for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
    			for(int i=0;i<=m;i++) c[i]=0;
    			for(int i=1;i<=n;i++) c[x[i]]++;
    			for(int i=1;i<=m;i++) c[i]+=c[i-1];
    			for(int i=n;i;--i) sa[c[x[y[i]]]--]=y[i];
    			swap(x,y);x[sa[1]]=p=1;
    			for(int i=2;i<=n;i++) x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && 
    				y[sa[i]+k]==y[sa[i-1]+k])?p:++p;
    			if(p>=n) break;
    			m=p;
    		}
    	}
    	void get_ht(int a[],int n=::n) {
    		for(int i=1;i<=n;i++) rk[sa[i]]=i;
    		for(int i=1,k=0,j;i<=n;ht[rk[i++]]=k)
    			for(j=sa[rk[i]-1],k=k?k-1:k;a[i+k]==a[j+k];k++);
    	}
    }
    
    int main() {
    	scanf("%s",s+1),n=strlen(s+1);
    	for(int i=1;i<=n;i++) a[i]=s[i]-'a'+1;
    	using namespace SuffixArray;
    	get_sa(a);get_ht(a);
    	for(int i=1;i<=n;i++) printf("%d%c",sa[i]," 
    "[i==n]);
    //	for(int i=1;i<=n;i++) cout<<rk[i]<<" ";cout<<endl;
    	for(int i=2;i<=n;i++) printf("%d%c",ht[i]," 
    "[i==n]);
    	return 0;
    }
    

      

    • Manacher (O(n)) 寻找最长回文串
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    const int N = 1000005;
    
    
    int p[N];
    char s[N];
    char ch[N];
    
    int Manacher(char s[]){
    	int l=strlen(s+1),mx=0,res=0,id=0;
    	
    //	cout<<l<<endl;
    	
    	memset(p,0,sizeof(p));
    	for(int i=1;i<=l;i++){
    		if(mx>i) p[i]=min(p[id*2-i],mx-i);
    		else p[i]=1;
    		while(s[i+p[i]]==s[i-p[i]]) p[i]++;
    		if(mx<i+p[i]) mx=i+p[i],id=i;
    	}
    	for(int i=1;i<=l;i++) res=max(p[i],res);
    	
    //	for(int i=1;i<=l;i++) cout<<p[i]<<" ";cout<<endl;
    	
    	return res-1;
    }
    
    int main(){
    	cin>>(s+1);ch[0]='$';ch[1]='#';
    	for(int i=1;i<=strlen(s+1);i++) ch[i*2]=s[i],ch[i*2+1]='#';
    //	cout<<(ch+1)<<endl;
    	cout<<Manacher(ch)<<endl;
    	return 0;
    }
    
    • 后缀自动机(SAM) (O(n))
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int N = 250005;
    
    struct State{
    	State *par,*go[26];
    	int val;
    	State(int _val):par(0),val(_val){ memset(go,0,sizeof(go)); }
    }*rt,*lst;
    void extend(int w){
    	State *p=lst,*np=new State(p->val+1);
    	while(p && p->go[w]==0) p->go[w]=np,p=p->par;
    	if(!p) np->par=rt;
    	else{
    		State *q=p->go[w];
    		if(q->val == p->val+1) np->par=q;
    		else{
    			State *nq=new State(p->val+1);
    			memcpy(nq->go,q->go,sizeof(q->go));
    			nq->par=q->par;
    			np->par=q->par=nq;
    			while(p && p->go[w]==q) p->go[w]=nq,p=p->par;
    		}
    	}lst=np;
    }
    
    int main(){ rt=new State(0),lst=rt; }
    

    数据结构

    • Treap (O(nlog n))
    #include <bits/stdc++.h>
    using namespace std;
    
    #define debug(a) cout<<(#a)<<"="<<a<<" "
    #define lc(o) ch[o][0]
    #define rc(o) ch[o][1]
    #define uor(i,j,k) for(int i=j;i<=(int)k;i++)
    #define uep(i,j,k) for(int i=j;i<(int)k;i++)
    #define dor(i,j,k) for(int i=j;i>=(int)k;i--)
    
    typedef long long ll;
    typedef pair<int,int> pr;
    typedef vector<int> vi;
    typedef vector<ll> vl;
    typedef vector<string> vs;
    const int N = 100050;
    const int M = 25;
    const int oo = 0x3fffffff;
    const ll  OO = 1e18;
    
    const ll p = 1000000007;
    ll Pow(ll a,ll b,ll r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
    ll Pow(ll a,ll b,ll p,ll r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
    ll inv(ll x) { return Pow(x,p-2); }
    void Add(ll &x,ll y) { x=(x+y%p)%p; }
    void Sub(ll &x,ll y) { x=(x-y%p+p)%p; }
    void Mul(ll &x,ll y) { x=x*(y%p)%p; }
    int chkmax(ll &x,ll y) { return x<y?x=y,1:0; }
    int chkmin(ll &x,ll y) { return x>y?x=y,1:0; }
    
    inline ll in(ll x=0,char ch=getchar(),int v=1) {
    	while(ch>'9' || ch<'0') v=ch=='-'?-1:v,ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x*v;
    }
    /*end*/
    
    namespace Treap {
    	int cp,rt;
    	
    	int sz[N],ss[N],ch[N][2],f[N],rv[N];
    	int val[N];
    	
    	int Newnode(int v) {
    		++cp,ss[cp]=sz[cp]=1,f[cp]=lc(cp)=rc(cp)=0,val[cp]=v,rv[cp]=rand();
    		return cp;
    	}
    	void init() { rt=0,rv[0]=-oo; }
    	void Update(int o) { sz[o]=sz[lc(o)]+sz[rc(o)]+ss[o]; }
    	void Rot(int &o,int d) {
    		int t=ch[o][d];ch[o][d]=ch[t][d^1],ch[t][d^1]=o,Update(o),Update(t),o=t;
    	}
    	void insert(int &o,int v) {
    		if(!o) { o=Newnode(v);return; }
    		if(val[o]==v) { ss[o]++,Update(o);return; }
    		int d=v>val[o];
    		insert(ch[o][d],v);
    		if(rv[ch[o][d]]>rv[o]) Rot(o,d);
    		else Update(o);
    	}
    	void earse(int &o,int v) {
    		if(val[o]==v) {
    			if(ss[o]>1) { ss[o]--,Update(o);return; }
    			int d=rv[lc(o)]<rv[rc(o)];
    			if(!ch[o][d]) { o=0;return; }
    			Rot(o,d),earse(ch[o][d^1],v);
    		}else earse(ch[o][v>val[o]],v);
    		Update(o);
    	}
    	int rk(int o,int v) {
    		if(val[o]<v) return sz[lc(o)]+ss[o]+rk(rc(o),v);
    		else if(val[o]>v) return rk(lc(o),v);
    		else return sz[lc(o)];
    	}
    	int kth(int o,int k) {
    		if(sz[lc(o)]>=k) return kth(lc(o),k);
    		else if(sz[lc(o)]+ss[o]<k) return kth(rc(o),k-sz[lc(o)]-ss[o]);
    		else return val[o];
    	}
    	int pre(int o,int v) {
    		if(!o) return -oo;
    		if(val[o]>=v) return pre(lc(o),v);
    		else return max(val[o],pre(rc(o),v));
    	}
    	int nxt(int o,int v) {
    		if(!o) return oo;
    		if(val[o]<=v) return nxt(rc(o),v);
    		else return min(val[o],nxt(lc(o),v));
    	}
    	void insert(int v) { insert(rt,v); }
    	void earse(int v) { earse(rt,v); }
    	int rk(int v) { return rk(rt,v); }
    	int kth(int k) { return kth(rt,k); }
    	int pre(int v) { return pre(rt,v); }
    	int nxt(int v) { return nxt(rt,v); }
    };
    
    int main() {
    	Treap::init();
    	for(int T=in();T--;) {
    		int opt=in(),x=in();
    		switch(opt) {
    			case 1:Treap::insert(x);break;
    			case 2:Treap::earse(x);break;
    			case 3:printf("%d
    ",Treap::rk(x)+1);break;
    			case 4:printf("%d
    ",Treap::kth(x));break;
    			case 5:printf("%d
    ",Treap::pre(x));break;
    			case 6:printf("%d
    ",Treap::nxt(x));break;
    		}
    	}
    	return 0;
    }
    

      

    • Splay (O(nlog n))
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 200050;
    
    inline LL in(LL x=0,char ch=getchar(),int v=1) {
    	while(ch>'9' || ch<'0') v=ch=='-'?-1:v,ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x*v;
    }
    
    int n,q,nw;
    LL a[N];
    
    struct SplayTree {
    	#define lc(o) ch[o][0]
    	#define rc(o) ch[o][1]
    	#define mid ((l+r)>>1)
    	
    	int cp,rt;
    	LL sum[N],v[N],d[N],rev[N],sz[N],f[N],ch[N][2];
    	
    	int NewNode() {
    		++cp;
    		sum[cp]=v[cp]=d[cp]=rev[cp]=lc(cp)=rc(cp)=0;
    		sz[cp]=1;
    		return cp;
    	}
    	void Update(int o) {
    		if(!o) return; 
    		sz[o]=sz[lc(o)]+sz[rc(o)]+1;
    		sum[o]=sum[lc(o)]+sum[rc(o)]+v[o]+d[o]*sz[o];
    	}
    	void Push(int o) {
    		if(!o) return;
    		Push(f[o]);
    		if(rev[o]) {
    			swap(lc(o),rc(o));
    			if(lc(o)) rev[lc(o)]^=1;
    			if(rc(o)) rev[rc(o)]^=1;
    			rev[o]=0;
    		}
    		if(d[o]) {
    			if(lc(o)) d[lc(o)]+=d[o];
    			if(rc(o)) d[rc(o)]+=d[o];
    			v[o]+=d[o],d[o]=0;
    		}Update(lc(o)),Update(rc(o)),Update(o);
    	}
    	void Pushdown(int o) {
    		if(!o) return;
    		if(rev[o]) {
    			swap(lc(o),rc(o));
    			if(lc(o)) rev[lc(o)]^=1;
    			if(rc(o)) rev[rc(o)]^=1;
    			rev[o]=0;
    		}
    		if(d[o]) {
    			if(lc(o)) d[lc(o)]+=d[o];
    			if(rc(o)) d[rc(o)]+=d[o];
    			v[o]+=d[o],d[o]=0;
    		}Update(lc(o)),Update(rc(o)),Update(o);
    	}
    	int Build(int l,int r) {
    		if(l>r){ return 0; }
    		int o=NewNode();
    		lc(o)=Build(l,mid-1);
    		v[o]=a[nw++];
    		rc(o)=Build(mid+1,r);
    		if(lc(o)) f[lc(o)]=o;
    		if(rc(o)) f[rc(o)]=o;
    		Update(o);
    		return o;
    	}
    	void Build(int n) {
    		rt=Build(1,n+2);
    	}
    	void Rot(int o) {
    		int p=f[o],k=f[p],r=rc(p)==o;
    //		Pushdown(k),Pushdown(p),Pushdown(o);
    		if(k) ch[k][rc(k)==p]=o;
    		f[p]=o,f[ch[o][r^1]]=p,f[o]=k;
    		ch[p][r]=ch[o][r^1],ch[o][r^1]=p;
    		Update(p),Update(o),Update(k);
    	}
    	void Splay(int o,int ff) {
    		Push(o);
    		for(;f[o]!=ff;) {
    			int p=f[o],k=f[p];
    			if(k!=ff) Rot((rc(k)==p)==(rc(p)==o)?p:o);
    			Rot(o);
    		}
    		Update(o);
    		if(!ff) rt=o;
    	}
    	int Kth(int o,int k) {
    		Pushdown(o);
    		if(sz[lc(o)]>=k) return Kth(lc(o),k);
    		else if(sz[lc(o)]+1==k) return o;
    		else return Kth(rc(o),k-sz[lc(o)]-1); 
    	}
    	LL Kthw(int o,int k) {
    		Pushdown(o);
    		if(sz[lc(o)]>=k) return Kthw(lc(o),k)+d[o];
    		else if(sz[lc(o)]+1==k) return v[o]+d[o];
    		else return Kthw(rc(o),k-sz[lc(o)]-1)+d[o]; 
    	}
    	LL Kthw(int k) { return Kthw(rt,k+1); }
    	void Add(int l,int r,LL w) {
    		l++,r++;
    		int L=Kth(rt,l-1),R=Kth(rt,r+1);
    		Splay(L,0),Splay(R,L);
    		d[lc(R)]+=w;
    		Update(lc(R)),Update(R),Update(L);
    	}
    	void Insert(int x,LL w) {
    		x++;
    		int L=Kth(rt,x),R=Kth(rt,x+1);
    		Splay(L,0),Splay(R,L);
    		int np=NewNode();lc(R)=np,v[np]=w,f[np]=R;
    		Update(np),Update(R),Update(L);
    	}
    	void Del(int l,int r) {
    		l++,r++;
    		int L=Kth(rt,l-1),R=Kth(rt,r+1);
    		Splay(L,0),Splay(R,L);
    		lc(R)=0,Update(R),Update(L);
    	}
    	LL Qur(int l,int r) {
    		l++,r++;
    		int L=Kth(rt,l-1),R=Kth(rt,r+1);
    		Splay(L,0),Splay(R,L);
    		return sum[lc(R)];
    	}
    	void Rev(int l,int r) {
    		l++,r++;
    		int L=Kth(rt,l-1),R=Kth(rt,r+1);
    		Splay(L,0),Splay(R,L);
    		rev[lc(R)]^=1;
    	}
    }py;
    
    int main() {
    	n=in();
    	for(int i=1;i<=n;i++) a[i]=in();
    	py.Build(n);
    	char opt[20];
    	int l,r,k,x,v;
    	for(q=in();q--;) {
    		scanf("%s",opt);
    		if(opt[0]=='A') l=in(),r=in(),v=in(),py.Add(l,r,v);
    		if(opt[0]=='I') x=in(),v=in(),py.Insert(x,v);
    		if(opt[0]=='D')	l=in(),r=in(),py.Del(l,r);
    		if(opt[0]=='Q') l=in(),r=in(),printf("%lld
    ",py.Qur(l,r));
    		if(opt[0]=='K') k=in(),printf("%lld
    ",py.Kthw(k));
    		if(opt[0]=='R')	l=in(),r=in(),py.Rev(l,r);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    局部测试用例,日常笔记
    软件测试工程师素养(日常笔记)
    Java控件(日常笔记)
    开发大体流程
    sort学习 LeetCode #406 Queue Reconstruction by Height
    MySQL 变量
    [转帖]查看结构体成员的大小和偏移地址的方法
    [转帖]SQL99
    static静态类 静态函数 静态字段
    默认构造函数
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5770820.html
Copyright © 2011-2022 走看看