模板柱(持续更新)

以下是本蒟蒻认为的NOIP范围内的所有模板,自认为写的又好懂又好记。按照基本算法->基本数据结构->数学->高级数据结构->图论的顺序编排,提供所有OJ模板题链接和代码。希望能帮助大家。

PDF链接

快速幂||取余运算

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
    Type x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}

LL a,b,p;

inline LL power(LL a,LL b,LL p){
    LL ans=1%p;
    for(;b;b>>=1){
        if(b&1)ans=ans*a%p;
        a=a*a%p;
    }
    return ans;
}

int main(){
    a=read<LL>();b=read<LL>();p=read<LL>();
    printf("%lld^%lld mod %lld=%lld
",a,b,p,power(a,b,p));
    return 0;
}

三分法

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=20;

#define eps 1e-6

int n;

double l,r,a[maxn];

inline double power(double a,int b){
	double ans=1.0;
	for(;b;b>>=1){
		if(b&1)ans=ans*a;
		a=a*a;
	}
	return ans;
}

inline double calc(double x){
	double ans=0.0;
	for(register int i=n;i>=0;--i){
		ans+=power(x,i)*a[i];
	}
	return ans;
}

inline void solve(void){
	while(r-l>=eps){
		double K=(r-l)/3.0;
		double lmid=l+K,rmid=r-K;
		if(calc(lmid)<calc(rmid))l=lmid;
		else r=rmid;
	}
}

int main(){
	n=read<int>();scanf("%lf%lf",&l,&r);
	for(register int i=n;i>=0;--i){
		scanf("%lf",a+i);
	}
	solve();
	printf("%.5lf",l);
	return 0;
}

ST表

洛谷模板

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=1e5+5;

int n,m,a[maxn];

int f[maxn][25];

inline void init(void){
	for(register int i=1;i<=n;++i)f[i][0]=a[i];
	for(register int j=1;j<=20;++j){
		for(register int i=1;i<=n-(1<<j)+1;++i){
			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		}
	}
}

int main(){
	n=read<int>();m=read<int>();
	for(register int i=1;i<=n;++i){
		a[i]=read<int>();
	}
	init();
	while(m--){
		int l=read<int>(),r=read<int>();
		if(l>r)swap(l,r);
		int k=log2(r-l+1);
		printf("%d
",max(f[l][k],f[r-(1<<k)+1][k]));
	}
	return 0;
}

字符串哈希

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int base=131,maxn=10005;

int n;

unsigned long long a[maxn];

char str[1005];

inline unsigned long long Hash(void){
	int len=strlen(str+1);unsigned long long ret=0;
	for(register int i=1;i<=len;++i){
		ret=ret*base+str[i]-'a'+1;
	}
	return ret;
}

int main(){
	n=read<int>();
	for(register int i=1;i<=n;++i){
		scanf("%s",str+1);
		a[i]=Hash();
	}
	sort(a+1,a+n+1);
	printf("%d
",unique(a+1,a+n+1)-a-1);
	return 0;
}

KMP字符串匹配

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=1000005;

char s1[maxn],s2[maxn];
int len1,len2,nxt[maxn],now,f[maxn];

int main(){
	scanf("%s",s2+1);len2=strlen(s2+1);
	scanf("%s",s1+1);len1=strlen(s1+1);//我习惯把小串称为s1串
	now=0;
	for(register int i=2;i<=len1;++i){
		while(now&&s1[i]!=s1[now+1])now=nxt[now];
		if(s1[i]==s1[now+1])++now;
		nxt[i]=now;
	}
	now=0;
	for(register int i=1;i<=len2;++i){
		if(now&&(now==len1||s2[i]!=s1[now+1]))now=nxt[now];
		if(s2[i]==s1[now+1])++now;
		f[i]=now;
		if(f[i]==len1)printf("%d
",i-len1+1);
	}
	for(register int i=1;i<=len1;++i)printf("%d ",nxt[i]);
	puts("");
	return 0;
}

manacher算法

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=11000005;

int n,hw[maxn<<1],ans;
char str[maxn],s[maxn<<1];

inline void change(void){
	s[0]=s[1]='#';
	for(register int i=0;i<n;++i){
		s[i*2+2]=str[i];
		s[i*2+3]='#';
	}
	n=n*2+2;
	s[n]=0;
}

inline void manacher(void){
	int maxright=0,mid=0;
	for(register int i=1;i<n;++i){
		if(i<maxright)
			hw[i]=min(hw[mid*2-i],maxright-i);
		else hw[i]=1;
		while(s[i+hw[i]]==s[i-hw[i]])++hw[i];
		if(hw[i]+i>maxright){
			maxright=hw[i]+i;mid=i;
		}
	}
}

int main(){
	scanf("%s",str);
	n=strlen(str);
	change();
	manacher();
	for(register int i=0;i<n;++i)ans=max(ans,hw[i]);
	cout<<ans-1<<endl;
	return 0;
}

Trie

hdu模板

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>

#define LL long long
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;
template<class Type>
inline Type read(void){
    Type x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return f*x;
}

const int maxn=1000005;

int trie[maxn][30],cnt[maxn*30],tot=1;

inline void Insert(char s[]){
    int p=1,len=strlen(s);
    for(register int i=0;i<len;++i){
        if(!trie[p][s[i]-'a'+1])trie[p][s[i]-'a'+1]=++tot;
        p=trie[p][s[i]-'a'+1];
        cnt[p]++;
    }
    return;
}

inline int query(char s[]){
    int p=1,len=strlen(s);
    for(register int i=0;i<len;++i){
        if(!trie[p][s[i]-'a'+1])return 0;
        p=trie[p][s[i]-'a'+1];
    }
    return cnt[p];
}

int main(){
    char ch[15];
    while(gets(ch)){
    	if(ch[0]==NULL)break;
    	Insert(ch);
	}
	while(gets(ch)){
		printf("%d
",query(ch));
	}
    return 0;
}

线性筛素数

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=10000005;

int n,m;

bool is_prime[maxn];
int priN,primes[maxn];

inline void find(void){
	mem(is_prime,true);
	is_prime[1]=false;
	for(register int i=2;i<=n;++i){
		if(is_prime[i])primes[++priN]=i;
		for(register int j=1;j<=priN;++j){
			if(i*primes[j]>n)break;
			is_prime[i*primes[j]]=false;
			if(i%primes[j]==0)break;
		}
	}
}

int main(){
	n=read<int>();m=read<int>();
	find();
	while(m--){
		int x=read<int>();
		if(is_prime[x])puts("Yes");
		else puts("No");
	}
	return 0;
}

裴蜀定理

洛谷模板

//首先这道题让我明白了裴蜀定理可以扩展到多个数的情况
//for example:设d=gcd(a,b,c),则ax+by+cz=k有整数解当且仅当d|k
//那这道题就求个gcd就好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=30;

int n,a[maxn],d;

inline int gcd(int a,int b){
	if(!b)return a;
	return gcd(b,a%b);
}

int main(){
	n=read<int>();
	for(register int i=1;i<=n;++i)a[i]=read<int>(),d=gcd(abs(a[i]),d);//要把负数变成正数!
	cout<<d<<endl;
	return 0;
}

扩展欧几里得算法

洛谷模板 (其实这不是一道裸的模板,但和模板差不了多少。)

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

int a,b;

inline int exgcd(int a,int b,int &x,int &y){
	if(b==0){x=1;y=0;return a;}
	int d=exgcd(b,a%b,x,y);
	int z=x;x=y;y=z-y*(a/b);
	return d;
}

int main(){
	a=read<int>();b=read<int>();
	int x=0,y=0;
	exgcd(a,b,x,y);
	cout<<(x%b+b)%b<<endl;
	return 0;
}

扩展中国剩余定理(EXCRT)

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=1e5+5;

int n;

LL a[maxn],m[maxn],lcm,now,k,d,x,y;

inline LL exgcd(LL a,LL b,LL &x,LL &y){
	if(b==0){x=1;y=0;return a;}
	LL d=exgcd(b,a%b,x,y);
	LL z=x;x=y;y=z-y*(a/b);
	return d;
}

inline LL mult(LL a,LL b,LL p){//快速乘
	LL ans=0;
	for(;b;b>>=1){
		if(b&1)ans=(ans+a)%p;
		a=(a+a)%p;
	}
	return ans;
}

int main(){
	n=read<int>();
	for(register int i=1;i<=n;++i){
		m[i]=read<LL>();
		a[i]=read<LL>();
	}
	lcm=m[1];now=a[1];bool fail=0;
	for(register int i=2;i<=n;++i){
		a[i]=(a[i]-now%m[i]+m[i])%m[i];
		d=exgcd(lcm,m[i],x,y);
		if(a[i]%d==0)k=mult(x,a[i]/d,m[i]);
		else {fail=1;break;}
		now+=k*lcm;
		lcm=lcm/d*m[i];
		now=(now%lcm+lcm)%lcm;
	}
	if(fail)cout<<"-1"<<endl;
	else cout<<now<<endl;
	return 0;
}

矩阵快速幂

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=105,mod=1e9+7;

int n;

struct Matrix{
	LL a[maxn][maxn];
	Matrix(){mem(a,0);}
	inline void init(void){
		for(register int i=1;i<=n;++i)a[i][i]=1;
	}
	inline friend Matrix operator *(const Matrix &x,const Matrix &y){
		Matrix z;
		for(register int i=1;i<=n;++i){
			for(register int j=1;j<=n;++j){
				for(register int k=1;k<=n;++k){
					(z.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod)%=mod;
				}
			}
		}
		return z;
	}
	inline friend Matrix operator ^(Matrix x,LL b){
		Matrix ans;ans.init();
		for(;b;b>>=1){
			if(b&1)ans=ans*x;
			x=x*x;
		}
		return ans;
	}
};

int main(){
	n=read<int>();LL K=read<LL>();
	Matrix cs;//初始矩阵
	for(register int i=1;i<=n;++i){
		for(register int j=1;j<=n;++j){
			cs.a[i][j]=read<LL>()%mod;
		}
	}
	cs=cs^K;
	for(register int i=1;i<=n;++i){
		for(register int j=1;j<=n;++j){
			printf("%lld ",cs.a[i][j]);
		}
		puts("");
	}
	return 0;
}

矩阵优化/矩阵加速

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int mod=1000000007;

LL n;

struct Matrix{
	LL a[3][3];
	Matrix(){mem(a,0);}
	inline void init(void){a[1][1]=a[2][2]=1;}
	inline void init2(void){
		a[1][1]=1;a[1][2]=1;
		a[2][1]=1;a[2][2]=0;
	}
	inline friend Matrix operator*(Matrix x,Matrix y){
		Matrix ans;
		for(register int i=1;i<=2;++i){
			for(register int j=1;j<=2;++j){
				for(register int k=1;k<=2;++k){
					(ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod)%=mod;
				}
			}
		}
		return ans;
	}
	inline friend Matrix operator^(Matrix x,LL b){
		Matrix ans;ans.init();
		for(;b;b>>=1){
			if(b&1)ans=ans*x;
			x=x*x;
		}
		return ans;
	}
};

inline void solve(void){
	Matrix cs;cs.init2();
	cs=cs^(n-2);
	cout<<(cs.a[1][1]+cs.a[2][1])%mod<<endl;
}

int main(){
	n=read<LL>();
	if(n==1)cout<<1<<endl;
	else if(n==2)cout<<1<<endl;
	else solve();
	return 0;
}

高斯消元法

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> 

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=105;

int n;double a[maxn][maxn],x[maxn];

#define eps 1e-7

inline bool gause(void){
	for(register int i=1;i<=n;++i){//枚举行 
		int k=i;
		for(register int j=i+1;j<=n;++j){//枚举行 
			if(fabs(a[k][i])<fabs(a[j][i]))k=j;
		}
		if(fabs(a[k][i])<eps)return false;
		for(register int j=i;j<=n+1;++j){//枚举列 
			swap(a[i][j],a[k][j]);
		}
		double Tmp=a[i][i];
		for(register int j=i;j<=n+1;++j){//枚举列 
			a[i][j]/=Tmp;
		}
		for(register int j=1;j<=n;++j){//枚举行 
			if(j==i)continue;
			double tmp=a[j][i];
			for(register int k=i;k<=n+1;++k){//枚举列 
				a[j][k]-=a[i][k]*tmp;
			}
		}
	}
	for(register int i=1;i<=n;++i)x[i]=a[i][n+1];
	return true;
}

int main(){
	n=read<int>();
	for(register int i=1;i<=n;++i){
		for(register int j=1;j<=n+1;++j){
			a[i][j]=read<int>();
		}
	}
	if(!gause()){
		puts("No Solution");return 0;
	}
	for(register int i=1;i<=n;++i)printf("%.2lf
",x[i]);
	return 0;
}

树状数组 1(单点修改、区间查询)

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=500005;

#define lowbit(x) x&(-x)

int n,q,a[maxn];

int tree[maxn];

inline void add(int p,int val){
	for(;p<=n;p+=lowbit(p)){
		tree[p]+=val;
	}
	return;
}

inline int sum(int p){
	int ret=0;
	for(;p;p-=lowbit(p)){
		ret+=tree[p];
	}
	return ret;
}

inline int query(int l,int r){
	return sum(r)-sum(l-1);
}

int main(){
	n=read<int>();q=read<int>();
	for(register int i=1;i<=n;++i){
		a[i]=read<int>();
		add(i,a[i]); 
	}
	while(q--){
		int opt=read<int>();
		if(opt==1){
			int x=read<int>(),k=read<int>();
			add(x,k);
		}
		else{
			int l=read<int>(),r=read<int>();
			cout<<query(l,r)<<endl;//李煜东:卡什么常啊,能不能有点追求!
		}
	}
	return 0;
}

树状数组 2(区间修改,单点查询)

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=500005;

#define lowbit(x) x&(-x)

int n,q,a[maxn];

int tree[maxn];

inline void add(int p,int val){
	for(;p<=n;p+=lowbit(p)){
		tree[p]+=val;
	}
	return;
}

inline int sum(int p){
	int ret=0;
	for(;p;p-=lowbit(p)){
		ret+=tree[p];
	}
	return ret;
}

int main(){
	n=read<int>();q=read<int>();
	for(register int i=1;i<=n;++i){
		a[i]=read<int>();
	}
	for(register int i=1;i<=n;++i){
		add(i,a[i]-a[i-1]);
	}
	while(q--){
		int opt=read<int>();
		if(opt==1){
			int l=read<int>(),r=read<int>(),val=read<int>();
			add(l,val);add(r+1,-val);
		}
		else{
			int x=read<int>();
			cout<<sum(x)<<endl;
		}
	}
	return 0;
}

树状数组求逆序对

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=5e5+5;

int n,a[maxn],b[maxn];LL ans;

#define lowbit(x) x&(-x)

LL tree[maxn];

inline void add(int p,int val){
	for(;p<=n;p+=lowbit(p)){
		tree[p]+=val;
	}
	return;
}

inline LL sum(int p){
	LL ret=0;
	for(;p;p-=lowbit(p)){
		ret+=tree[p];
	}
	return ret;
}

int main(){
	n=read<int>();
	for(register int i=1;i<=n;++i){
		a[i]=read<int>();b[i]=a[i];
	}
	sort(b+1,b+n+1);
	int len=unique(b+1,b+n+1)-b-1;
	for(register int i=1;i<=n;++i){
		a[i]=lower_bound(b+1,b+len+1,a[i])-b;
	}
	for(register int i=n;i>=1;--i){
		ans+=sum(a[i]-1);
		add(a[i],1);
	}
	cout<<ans<<endl;
	return 0;
}

普通线段树

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=100005;

int n,q;

LL a[maxn];

#define lson (o<<1)
#define rson (o<<1|1)

LL sum[maxn<<2],add[maxn<<2],len[maxn<<2];

inline void pushup(int o){
	sum[o]=sum[lson]+sum[rson];
}

inline void build(int o,int l,int r){
	len[o]=r-l+1;
	if(l==r){sum[o]=a[l];return;}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(o);
}

inline void Add(int o,int val){
	add[o]+=val;
	sum[o]+=len[o]*val;
}

inline void pushdown(int o){
	if(!add[o])return;
	Add(lson,add[o]);Add(rson,add[o]);
	add[o]=0;
}

inline void Update(int o,int l,int r,int ql,int qr,LL v){
	if(ql<=l&&r<=qr){Add(o,v);return;}
	pushdown(o);
	int mid=(l+r)>>1;
	if(ql<=mid)Update(lson,l,mid,ql,qr,v);
	if(qr>mid)Update(rson,mid+1,r,ql,qr,v);
	pushup(o);
}

inline LL query(int o,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr)return sum[o];
	pushdown(o);
	int mid=(l+r)>>1;LL ans=0;
	if(ql<=mid)ans+=query(lson,l,mid,ql,qr);
	if(qr>mid)ans+=query(rson,mid+1,r,ql,qr);
	return ans;
}

int main(){
	n=read<int>();q=read<int>();
	for(register int i=1;i<=n;++i){
		a[i]=read<LL>();
	}
	build(1,1,n);
	while(q--){
		int opt=read<int>();
		if(opt==1){
			int l=read<int>(),r=read<int>();LL val=read<LL>();
			Update(1,1,n,l,r,val);
		}
		else{
			int l=read<int>(),r=read<int>();
			printf("%lld
",query(1,1,n,l,r));
		}
	}
	return 0;
}

支持乘法和加法的线段树

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=100005;

int n,m;
LL p,a[maxn];

struct Segment_Tree{
#define lson (o<<1)
#define rson (o<<1|1)
	LL addm[maxn<<2],addp[maxn<<2],sum[maxn<<2],len[maxn<<2];
	inline void pushup(int o){
		sum[o]=sum[lson]+sum[rson];
	}
	inline void build(int o,int l,int r){
		len[o]=r-l+1;
		sum[o]=addp[o]=0;
		addm[o]=1;
		if(l==r){sum[o]=a[l];return;}
		int mid=(l+r)>>1;
		build(lson,l,mid);build(rson,mid+1,r);
		pushup(o);
	}
	inline void Plus(int o,LL val){
		(addp[o]+=val)%=p;
		(sum[o]+=len[o]*val)%=p;
	}
	inline void Mult(int o,LL val){
		(sum[o]*=val)%=p;
		(addm[o]*=val)%=p;
		(addp[o]*=val)%=p;
		return;
	}
	inline void pushdown(int o){
		if(!addp[o]&&addm[o]==1)return;
		Mult(lson,addm[o]);Mult(rson,addm[o]);
		Plus(lson,addp[o]);Plus(rson,addp[o]);
		addp[o]=0;addm[o]=1;
		return;
	}
	inline void Update(int o,int l,int r,int ql,int qr,LL v,int k){
		if(ql<=l&&r<=qr){
			switch(k){
				case 1:Mult(o,v);break;
				case 2:Plus(o,v);break;
			}
			return;
		}
		pushdown(o);
		int mid=(l+r)>>1;
		if(ql<=mid)Update(lson,l,mid,ql,qr,v,k);
		if(qr>mid)Update(rson,mid+1,r,ql,qr,v,k);
		pushup(o);
	}
	inline LL query(int o,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr)return sum[o];
		pushdown(o);
		int mid=(l+r)>>1;LL ans=0;
		if(ql<=mid)(ans+=query(lson,l,mid,ql,qr))%=p;
		if(qr>mid)(ans+=query(rson,mid+1,r,ql,qr))%=p;
		return ans;
	}
}T;

int main(){
	n=read<int>();m=read<int>();p=read<LL>();
	for(register int i=1;i<=n;++i)a[i]=read<LL>();
	T.build(1,1,n);
	while(m--){
		int opt=read<int>(),l=read<int>(),r=read<int>();LL v=0;
		switch(opt){
			case 1:v=read<LL>();T.Update(1,1,n,l,r,v,1);break;
			case 2:v=read<LL>();T.Update(1,1,n,l,r,v,2);break;
			case 3:printf("%lld
",T.query(1,1,n,l,r));break;
		}
	}
	return 0;
}

分块

洛谷模板(同线段树的模板)

//我发现一个可怕的事实:
//我的分块比线段树快!!!
//我现在正纠结于考场上写分块还是线段树……
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=100005;

int n,m,t,R[maxn],L[maxn],bl[maxn];
LL a[maxn],sum[maxn],add[maxn];

inline void Update(int l,int r,LL val){
	int p=bl[l],q=bl[r];
	if(p==q){
		for(register int i=l;i<=r;++i)a[i]+=val;
		sum[p]+=val*(r-l+1);
	}
	else{
		for(register int i=p+1;i<=q-1;++i)add[i]+=val;
		for(register int i=l;i<=R[p];++i)a[i]+=val;
		sum[p]+=val*(R[p]-l+1);
		for(register int i=L[q];i<=r;++i)a[i]+=val;
		sum[q]+=val*(r-L[q]+1);
	}
}

inline LL query(int l,int r){
	int p=bl[l],q=bl[r];LL ret=0;
	if(p==q){
		for(register int i=l;i<=r;++i)ret+=a[i];
		ret+=add[p]*(r-l+1);
	}
	else{
		for(register int i=p+1;i<=q-1;++i)
			ret+=sum[i]+add[i]*(R[i]-L[i]+1);
		for(register int i=l;i<=R[p];++i)ret+=a[i];
		ret+=add[p]*(R[p]-l+1);
		for(register int i=L[q];i<=r;++i)ret+=a[i];
		ret+=add[q]*(r-L[q]+1);
	}
	return ret;
}

int main(){
	n=read<int>();m=read<int>();
	for(register int i=1;i<=n;++i)a[i]=read<LL>();
	t=sqrt(n);
	for(register int i=1;i<=t;++i){
		L[i]=(i-1)*t+1;
		R[i]=i*t;
	}
	if(R[t]<n)++t,L[t]=R[t-1]+1,R[t]=n;
	for(register int i=1;i<=t;++i){
		for(register int j=L[i];j<=R[i];++j){
			bl[j]=i;
			sum[i]+=a[j];
		}
	}
	while(m--){
		int opt=read<int>(),l=read<int>(),r=read<int>();
		if(opt==1){
			LL v=read<LL>();
			Update(l,r,v);
		}
		else{
			printf("%lld
",query(l,r));
		}
	}
	return 0;
}

普通平衡树(01trie)

洛谷模板

//我之所以选择这个不太著名的数据结构来当做普通平衡树的模板,是因为这玩意代码又短常数又小,我非常喜欢它!
#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int base=1e7,maxn=100005;

int q;

int trie[35*maxn][2],tot=1,tag[32*maxn];

inline void insert(int val,int d){
	int p=1;val+=base;
	for(register int i=31;~i;--i){
		int tmp=(val>>i)&1;
		if(!trie[p][tmp])trie[p][tmp]=++tot;
		p=trie[p][tmp];tag[p]+=d;
	}
}

inline int rank(int val){
	int p=1,ret=0;val+=base;
	for(register int i=31;~i;--i){
		int tmp=(val>>i)&1;
		if(tmp)ret+=tag[trie[p][0]];
		p=trie[p][tmp];
	}
	return ret+1;
}

inline int kth(int rank){
	int ret=0,p=1;
	for(register int i=31;~i;--i){
		if(rank>tag[trie[p][0]])rank-=tag[trie[p][0]],ret|=(1<<i),p=trie[p][1];
		else p=trie[p][0];
	}
	ret-=base;
	return ret;
}

int main(){
	q=read<int>();
	while(q--){
		int opt=read<int>(),x=read<int>();
		switch(opt){
			case 1:insert(x,1);break;
			case 2:insert(x,-1);break;
			case 3:printf("%d
",rank(x));break;
			case 4:printf("%d
",kth(x));break;
			case 5:printf("%d
",kth(rank(x)-1));break;
			case 6:printf("%d
",kth(rank(x+1)));break;
		}
	}
	return 0;
}

普通平衡树(Splay)

洛谷原题

#include <iostream>
#include <cstdio>
#include <cstring>

#define LL long long
#define mem(s, v) memset(s, v, sizeof s)

using namespace std;
inline LL read(void) {
	LL x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return f * x;
}

const int maxn = 1100005, inf = 0x7fffffff;

int n, m;

struct Balance_Tree {
	int son[maxn][2], cnt[maxn], siz[maxn], fa[maxn], key[maxn], root, sz;
	inline void clear(int x) {
		son[x][0] = son[x][1] = cnt[x] = siz[x] = fa[x] = key[x] = 0;
	}
	inline int get(int x) { return son[fa[x]][1] == x; }
	inline void update(int x) {
		if (!x) return;
		siz[x] = cnt[x];
		if (son[x][0]) siz[x] += siz[son[x][0]];
		if (son[x][1]) siz[x] += siz[son[x][1]];
	}
	inline void rotate(int x) {
		int y = fa[x], z = fa[y], k = get(x);
		fa[y] = x; son[y][k] = son[x][k ^ 1]; fa[son[y][k]] = y;
		son[x][k ^ 1] = y; fa[x] = z;
		if (z) son[z][son[z][1] == y] = x;
		update(y); update(x);
	}
	inline void splay(int x) {
		for (int f; (f = fa[x]); rotate(x)) {
			if (fa[f])
				rotate((get(x) == get(f)) ? f : x);
		}
		root = x;
	}
	int find_closest(int x, int val) {
		if (key[x] == val) return x;
		if (val < key[x]) return (son[x][0] ? find_closest(son[x][0], val) : x);
		if (val > key[x]) return (son[x][1] ? find_closest(son[x][1], val) : x);
	}
	inline void find(int val) {
		splay(find_closest(root, val));
		if (key[root] >= val) return;
		int now = son[root][1];
		while (son[now][0]) now = son[now][0];
		splay(now);
	}
	inline int rank(int val) {
		find(val);
		return siz[son[root][0]] + 1;
	}
	inline int kth(int x, int k) {
		if (siz[son[x][0]] >= k) return kth(son[x][0], k);
		if (siz[son[x][0]] + cnt[x] >= k) return key[x];
		return kth(son[x][1], k - siz[son[x][0]] - cnt[x]);
	}
	inline int pre(int val) {
		int tmp = rank(val) - 1;
		return kth(root, tmp);
	} 
	inline int nxt(int val) {
		int tmp = rank(val + 1);
		return kth(root, tmp);
	}
	inline void insert(int val) {
		if (!root) {
			root = ++sz; son[root][0] = son[root][1] = fa[root] = 0;
			siz[root] = cnt[root] = 1; key[root] = val; return;
		}
		find(val);
		if (key[root] == val) { ++cnt[root]; ++siz[root]; return; }
		key[++sz] = val; cnt[sz] = 1;
		fa[son[root][0]] = sz;
		son[sz][0] = son[root][0]; fa[sz] = root;
		son[root][0] = sz;
		update(sz); update(root);
	}
	inline void del(int val) {
		find(val);
		if (cnt[root] >= 2) { --cnt[root]; --siz[root]; return; }
		int old = root;
		if (!son[root][0]) { fa[son[root][1]] = 0; root = son[root][1]; clear(old); return; }
		if (!son[root][1]) { fa[son[root][0]] = 0; root = son[root][0]; clear(old); return; }
		find(pre(val));
		old = son[root][1];
		fa[son[old][1]] = root; 
		son[root][1] = son[old][1];
		clear(old);
		update(root);
	}
}T;

int main() {
	n = read(); m = read();
	T.insert(inf);
	for (register int i = 1; i <= n; ++i) {
		T.insert(read());
	}
	int ans = 0, lst = 0, x, opt;
	while (m--) {
		opt = read(); x = read() ^ lst;
		switch (opt) {
		case 1: T.insert(x); break;
		case 2: T.del(x); break;
		case 3: lst = T.rank(x); ans ^= lst; break;
		case 4: lst = T.kth(T.root, x); ans ^= lst; break;
		case 5: lst = T.pre(x); ans ^= lst; break;
		case 6: lst = T.nxt(x); ans ^= lst; break;
		default: puts("Wish you a happy day!"); break;
		}
	}
	printf("%d
", ans);
	return 0;
}

单源最短路径

洛谷模板

//不要用SPFA!
//不要用SPFA!
//不要用SPFA!
//重要的事情说三遍。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=100005,maxm=200005;

int n,m,st;

int head[maxn],tot,dis[maxn];

bool vis[maxn];

struct Edge{
	int y,next,w;
	Edge(){}
	Edge(int _y,int _next,int _w):y(_y),next(_next),w(_w){}
}e[maxm];

inline void connect(int x,int y,int w){
	e[++tot]=Edge(y,head[x],w);
	head[x]=tot;
}

priority_queue<pair<int,int> >q;

inline void Dijkstra(void){
	q.push(make_pair(0,st));
	mem(dis,0x3f);dis[st]=0;
	while(q.size()){
		int x=q.top().second;q.pop();
		if(vis[x])continue;
		vis[x]=true;
		for(register int i=head[x];i;i=e[i].next){
			int y=e[i].y;
			if(dis[y]>dis[x]+e[i].w){
				dis[y]=dis[x]+e[i].w;
				q.push(make_pair(-dis[y],y));
			}
		}
	}
}

int main(){
	n=read<int>();m=read<int>();st=read<int>();
	for(register int i=1;i<=m;++i){
		int x=read<int>(),y=read<int>(),w=read<int>();
		connect(x,y,w);
	}
	Dijkstra();
	for(register int i=1;i<=n;++i)printf("%d ",dis[i]);
	return 0;
}

Kruskal

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxm=200005,maxn=5005;

int n,m;

int fa[maxn];

struct Group{
	int x,y,w;
	Group(){}
	Group(int _x,int _y,int _w):x(_x),y(_y),w(_w){}
	inline friend bool operator <(const Group &a,const Group &b){
		return a.w<b.w;
	}
}e[maxm];

inline int find(int x){
	if(x==fa[x])return x;
	return fa[x]=find(fa[x]);
}

int main(){
	n=read<int>();m=read<int>();
	for(register int i=1;i<=n;++i)fa[i]=i;
	for(register int i=1;i<=m;++i){
		int x=read<int>(),y=read<int>(),w=read<int>();
		e[i]=Group(x,y,w);
	}
	sort(e+1,e+m+1);
	int ans=0,tot=0;
	for(register int i=1;i<=m;++i){
		int u=e[i].x,v=e[i].y;
		u=find(u),v=find(v);
		if(u==v)continue;
		fa[u]=v;
		++tot;
		ans+=e[i].w;
		if(tot==n-1)break;
	}
	printf("%d
",ans);
	return 0;
}

Prim

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=5005;

int n,m,G[maxn][maxn],d[maxn],ans;
bool vis[maxn];

int main(){
	n=read<int>();m=read<int>();
	mem(G,0x3f);
	for(register int i=1;i<=n;++i)G[i][i]=0;
	for(register int i=1;i<=m;++i){
		int x=read<int>(),y=read<int>(),w=read<int>();
		G[y][x]=G[x][y]=min(G[x][y],w);
	}
	mem(d,0x3f);
	d[1]=0;
	for(register int i=1;i<n;++i){
		int x=0;
		for(register int j=1;j<=n;++j){
			if(!vis[j]&&(x==0||d[j]<d[x]))x=j;
		}
		vis[x]=true;
		for(register int y=1;y<=n;++y){
			if(!vis[y])d[y]=min(d[y],G[x][y]);
		}
	}
	for(register int i=2;i<=n;++i)ans+=d[i];
	printf("%d
",ans);
	return 0;
}

倍增LCA

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=500005;

int n,m,head[maxn],tot,fa[maxn][30],dep[maxn],st;

struct Edge{
	int y,next;
	Edge(){}
	Edge(int _y,int _next):y(_y),next(_next){}
}e[maxn<<1];

inline void connect(int x,int y){
	e[++tot]=Edge(y,head[x]);
	head[x]=tot;
}

void dfs(int x,int father,int depth){
	fa[x][0]=father;
	for(register int j=1;j<=20;++j){
		fa[x][j]=fa[fa[x][j-1]][j-1];
	}
	dep[x]=depth;
	for(register int i=head[x];i;i=e[i].next){
		int y=e[i].y;
		if(y==father)continue;
		dfs(y,x,depth+1);
	}
}

inline int lca(int x,int y){
	if(dep[x]<dep[y])x^=y^=x^=y;//swap(x,y)
	for(register int i=20;i>=0;--i){
		if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
	}
	if(x==y)return x;
	for(register int i=20;i>=0;--i){
		if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
	}
	return fa[x][0];
}

int main(){
	n=read<int>();m=read<int>();st=read<int>();
	for(register int i=1;i<n;++i){
		int x=read<int>(),y=read<int>();
		connect(x,y);
		connect(y,x);
	}
	dfs(st,0,1);
	while(m--){
		int x=read<int>(),y=read<int>();
		printf("%d
",lca(x,y));
	}
	return 0;
}

SPFA判负环

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=2005,maxm=3005;

int T;

int head[maxn],tot,n,m,dis[maxn],cnt[maxn];
bool vis[maxn];

struct Edge{
	int y,next,w;
	Edge(){}
	Edge(int _y,int _next,int _w):y(_y),next(_next),w(_w){}
}e[maxm<<1];

inline void connect(int x,int y,int w){
	e[++tot]=Edge(y,head[x],w);
	head[x]=tot;
}

inline void clear(void){
	mem(head,0);mem(e,0);tot=0;
}

inline bool spfa(void){
	queue<int>q;q.push(1);
	mem(dis,0x3f);dis[1]=0;
	mem(vis,0);vis[1]=true;
	mem(cnt,0);cnt[1]=1;
	while(q.size()){
		int x=q.front();q.pop();vis[x]=false;
		for(register int i=head[x];i;i=e[i].next){
			int y=e[i].y;
			if(dis[y]>dis[x]+e[i].w){
				dis[y]=dis[x]+e[i].w;
				cnt[y]=cnt[x]+1;
				if(cnt[y]>n)return true;
				if(!vis[y]){
					q.push(y);vis[y]=true;
				}
			}
		}
	}
	return false;
}

int main(){
	T=read<int>();
	while(T--){
		clear();
		n=read<int>();m=read<int>();
		for(register int i=1;i<=m;++i){
			int x=read<int>(),y=read<int>(),w=read<int>();
			if(w<0)connect(x,y,w);
			else connect(x,y,w),connect(y,x,w);
		}
		if(spfa())puts("YE5");
		else puts("N0");
	}
	return 0;
}

缩点

洛谷模板

//话说这能叫模板吗?QWQ
//一个常识:在有向无环图上的DP一般都要拓扑排序。
//包括期望DP。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=10005,maxm=100005;

int n,m,val[maxn];

int head[maxn],tot,head_new[maxn],tot_new;

int dfn[maxn],low[maxn],stack[maxn],top,bl[maxn],cnt,num,siz[maxn];
bool ins[maxn];

int in[maxn],dp[maxn],ans;
bool vis[maxn];

struct Edge{
	int y,next;
	Edge(){}
	Edge(int _y,int _next):y(_y),next(_next){}
}e[maxm],e_new[maxm];

inline void connect(int x,int y){
	e[++tot]=Edge(y,head[x]);
	head[x]=tot;
}

inline void connect_new(int x,int y){
	e_new[++tot_new]=Edge(y,head_new[x]);
	head_new[x]=tot_new;
}

void Tarjan(int x){
	low[x]=dfn[x]=++num;
	stack[++top]=x;ins[x]=true;
	for(register int i=head[x];i;i=e[i].next){
		int y=e[i].y;
		if(!dfn[y]){
			Tarjan(y);
			low[x]=min(low[x],low[y]);
		}else if(ins[y]){
			low[x]=min(low[x],dfn[y]);
		}
	}
	if(dfn[x]==low[x]){
		int y;++cnt;
		do{
			y=stack[top--];ins[y]=false;
			bl[y]=cnt;siz[cnt]+=val[y];
		}while(x!=y);
	}
}

inline void topsort(void){
	queue<int>q;
	for(register int i=1;i<=cnt;++i){
		if(!in[i]){q.push(i);dp[i]=siz[i];ans=max(ans,dp[i]);}
	}
	while(q.size()){
		int x=q.front();q.pop();
		for(register int i=head_new[x];i;i=e_new[i].next){
			int y=e_new[i].y;
			--in[y];
			if(!in[y]){
				dp[y]=max(dp[y],dp[x]+siz[y]);
				ans=max(ans,dp[y]);
				q.push(y);
			}
		}
	}
}

int main(){
	n=read<int>();m=read<int>();
	for(register int i=1;i<=n;++i)val[i]=read<int>();
	for(register int i=1;i<=m;++i){
		int x=read<int>(),y=read<int>();
		connect(x,y);
	}
	for(register int i=1;i<=n;++i)if(!dfn[i])Tarjan(i);
	for(register int x=1;x<=n;++x){
		for(register int i=head[x];i;i=e[i].next){
			int y=e[i].y;
			if(bl[x]!=bl[y])connect_new(bl[x],bl[y]),++in[bl[y]];
		}
	}
	topsort();
	printf("%d
",ans);
	return 0;
}

二分图匹配

洛谷模板

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;

template<class Type>
inline Type read(void){
	Type x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}

const int maxn=2005,maxm=1005*1005;

int n,m,E;

int head[maxn],tot,ans;

int match[maxn];
bool v[maxn];

struct Edge{
	int y,next;
	Edge(){}
	Edge(int _y,int _next):y(_y),next(_next){}
}e[maxm<<1];

inline void connect(int x,int y){
	e[++tot]=Edge(y,head[x]);
	head[x]=tot;
}

bool dfs(int x){
	for(register int i=head[x];i;i=e[i].next){
		int y=e[i].y;
		if(!v[y]){
			v[y]=true;
			if(!match[y]||dfs(match[y])){
				match[y]=x;return true;
			}
		}	
	}
	return false;
}

int main(){
	n=read<int>();m=read<int>();E=read<int>();
	for(register int i=1;i<=E;++i){
		int x=read<int>(),y=read<int>()+n;
		if(y-n>m)continue;//为了防毒瘤数据
		connect(x,y);
	}
	for(register int i=1;i<=n;++i){
		mem(v,0);
		if(dfs(i))++ans;
	}
	cout<<ans<<endl;
	return 0;
}

原文地址:https://www.cnblogs.com/little-aztl/p/9807617.html