模板

checker

#include<bits/stdc++.h>
using namespace std;
int main(){
	string t="";
	for(int i=1;i<=;i++){
		string s=to_string(i);
		system((t+".exe < "+t+s+".in > "+t+".out").c_str());
		system(("fc "+t+".out "+t+s+".ans").c_str());
	}
//	while(1){
//		system(("data.exe > "+t+".in").c_str());
//		system((t+".exe < "+t+".in > "+t+".out").c_str());
//		system(("force.exe < "+t+".in > force.out").c_str());
//		if(system(("fc "+t+".out force.out").c_str()))break;
//	}
	return 0;
}

快读

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
int main(){
	return 0;
}

网络流

网络最大流

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace IO{
#define gc getchar
#define pc putchar
#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=205,M=10005,inf=1e15;
int n,m,S,T,tot=-1,h[N];
struct edge{int v,f,nxt;}e[M];
void add(int u,int v,int f){e[++tot]={v,f,h[u]},h[u]=tot;}
namespace Flow{
	int d[N],st[N];
	void Add(int u,int v,int f){add(u,v,f),add(v,u,0);}
	bool bfs(){
		for(int i=1;i<=n;i++)d[i]=-1;
		queue<int>q;
		d[S]=0,q.push(S);
		while(!q.empty()){
			int u=q.front();
			q.pop();
			for(int i=h[u];~i;i=e[i].nxt){
				int v=e[i].v,f=e[i].f;
				if(!~d[v]&&f){
					d[v]=d[u]+1,q.push(v);
					if(v==T)return 1;
				}
			}
		}
		return 0;
	}
	int dfs(int u,int F){
		if(!F||u==T)return F;
		int x=0;
		for(int i=st[u];~i;i=e[i].nxt){
			st[u]=i;
			int v=e[i].v,f=e[i].f;
			if(d[v]<=d[u])continue;
			int y=dfs(v,min(F-x,f));
			e[i].f-=y,e[i^1].f+=y,x+=y;
			if(x==F)break;
		}
		return x;
	}
	int dinic(){
		int x=0;
		while(bfs()){
			for(int i=1;i<=n;i++)st[i]=h[i];
			x+=dfs(S,inf);
		}
		return x;
	}
}
using namespace Flow;
signed main(){
	n=in(),m=in(),S=in(),T=in();
	for(int i=1;i<=n;i++)h[i]=-1;
	for(int i=1;i<=m;i++){
		int u=in(),v=in(),f=in();
		Add(u,v,f);
	}
	out(dinic());
}

最小费用最大流

SPFA

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e3,M=1e5,inf=1ll<<31;
int n,m,cnt=-1,h[N+5];
struct edge{int v,c,w,nxt;}e[M+5];
void add(int u,int v,int c,int w){
	e[++cnt]={v,c,w,h[u]},h[u]=cnt;
	e[++cnt]={u,0,-w,h[v]},h[v]=cnt;
}
namespace Flow{
	int s,t,ansf,answ,dis[N+5],st[N+5];
	bool vis[N+5];
	queue<int>q;
	bool spfa(){
		for(int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;
		while(!q.empty())q.pop();
		dis[s]=0,vis[s]=1;
		q.push(s);
		while(!q.empty()){
			int u=q.front();
			q.pop();
			vis[u]=0;
			for(int i=h[u];~i;i=e[i].nxt){
				int v=e[i].v,c=e[i].c,w=e[i].w;
				if(c&&dis[v]>dis[u]+w){
					dis[v]=dis[u]+w;
					if(!vis[v]){
						vis[v]=1;
						q.push(v);
					}
				}
			}
		}
		return dis[t]<inf;
	}
	int dfs(int u,int f){
		if(!f||u==t)return f;
		int sum=0;
		vis[u]=1;
		for(int i=st[u];~i;i=e[i].nxt){
			st[u]=i;
			int v=e[i].v,c=e[i].c,w=e[i].w;
			if(vis[v]||dis[v]<dis[u]+w)continue;
			int now=dfs(v,min(f-sum,c));
			if(now){
				answ+=now*w;
				e[i].c-=now,e[i^1].c+=now;
				sum+=now;
				if(f==sum)break;
			}
		}
		vis[u]=0;
		return sum;
	}
	void dinic(){
		while(spfa()){
			for(int i=1;i<=n;i++)st[i]=h[i],vis[i]=0;
			ansf+=dfs(s,inf);
		}
	}
}
using namespace Flow;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m>>s>>t;
	for(int i=1;i<=n;i++)h[i]=-1;
	for(int i=1;i<=m;i++){
		int u,v,c,w;
		cin>>u>>v>>c>>w;
		add(u,v,c,w);
	}
	dinic();
	cout<<ansf<<' '<<answ;
}

dijkstra

#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
using namespace std;
const int N=5e3,M=1e5,inf=1ll<<31;
int n,m,cnt=-1,h[N+5];
struct edge{int v,c,w,nxt;}e[M+5];
void add(int u,int v,int c,int w){
	e[++cnt]={v,c,w,h[u]},h[u]=cnt;
	e[++cnt]={u,0,-w,h[v]},h[v]=cnt;
}
namespace Flow{
	int s,t,ansf,answ,dis[N+5],pe[N+5],st[N+5];
	bool vis[N+5];
	priority_queue<pii>q;
	bool dijkstra(){
		for(int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;
		while(!q.empty())q.pop();
		dis[s]=0;
		q.push({0,s});
		while(!q.empty()){
			int u=q.top().second;
			q.pop();
			if(vis[u])continue;
			vis[u]=1;
			for(int i=h[u];~i;i=e[i].nxt){
				int v=e[i].v,c=e[i].c,w=e[i].w+pe[u]-pe[v];
				if(c&&dis[v]>dis[u]+w){
					dis[v]=dis[u]+w;
					q.push({-dis[v],v});
				}
			}
		}
		return dis[t]<inf;
	}
	int dfs(int u,int f){
		if(!f||u==t)return f;
		int sum=0;
		vis[u]=1;
		for(int i=st[u];~i;i=e[i].nxt){
			st[u]=i;
			int v=e[i].v,c=e[i].c,w=e[i].w+pe[u]-pe[v];
			if(vis[v]||dis[v]<dis[u]+w)continue;
			int now=dfs(v,min(f-sum,c));
			if(now){
				answ+=now*e[i].w;
				e[i].c-=now,e[i^1].c+=now;
				sum+=now;
				if(f==sum)break;
			}
		}
		vis[u]=0;
		return sum;
	}
	void dinic(){
		while(dijkstra()){
			for(int i=1;i<=n;i++)st[i]=h[i],vis[i]=0;
			ansf+=dfs(s,inf);
			for(int i=1;i<=n;i++)if(dis[i]<inf)pe[i]+=dis[i];
		}
	}
}
using namespace Flow;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m>>s>>t;
	for(int i=1;i<=n;i++)h[i]=-1;
	for(int i=1;i<=m;i++){
		int u,v,c,w;
		cin>>u>>v>>c>>w;
		add(u,v,c,w);
	}
	dinic();
	cout<<ansf<<' '<<answ;
}

有源汇上下界最大流

树上问题

LCA

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=5e5,L=20;
int n,q,r,tot,dfn[N+5],id[N+5],st[L+5][N+5];
vector<int> g[N+5];
void dfs(int u,int f){
	dfn[u]=++tot,id[tot]=u,st[0][tot]=dfn[f];
	for(int v:g[u])if(v!=f)dfs(v,u);
}
int lca(int u,int v){
	if(u==v)return u;
	if(dfn[u]>dfn[v])swap(u,v);
	int l=dfn[u]+1,r=dfn[v],x=__lg(r-l+1);
	return id[min(st[x][l],st[x][r-(1<<x)+1])];
}
int main(){
	n=in(),q=in(),r=in();
	for(int i=1;i<n;i++){
		int u=in(),v=in();
		g[u].pb(v),g[v].pb(u);
	}
	dfs(r,0);
	for(int i=1;i<=L;i++)for(int j=1;j+(1<<i)-1<=n;j++)st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
	while(q--){
		int u=in(),v=in();
		outln(lca(u,v));
	}
	return 0;
}

线段树合并

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=1e5,M=1e7,L=20;
int n,q,now,ans[N+5],dfn[N+5],fa[N+5][L+5];
vector<int> g[N+5];
namespace SGT{
	int tot,rt[N+5],a[M+5],sum[M+5],ls[M+5],rs[M+5];
	#define lm ((l+r)>>1)
	#define rm (lm+1)
	inline void pushup(int x){
		if(sum[ls[x]]>=sum[rs[x]])a[x]=a[ls[x]],sum[x]=sum[ls[x]];
		else a[x]=a[rs[x]],sum[x]=sum[rs[x]];
	}
	void update(int &x,int l,int r,int p,int q){
		if(l>p||r<p)return;
		if(!x)x=++tot;
		if(l==r){
			a[x]=p;
			sum[x]+=q;
			return;
		}
		update(ls[x],l,lm,p,q),update(rs[x],rm,r,p,q);
		pushup(x);
	}
	int merge(int u,int v,int l,int r){
		if(!u||!v)return u+v;
		if(l==r){
			sum[u]+=sum[v];
			return u;
		}
		ls[u]=merge(ls[u],ls[v],l,lm),rs[u]=merge(rs[u],rs[v],rm,r);
		pushup(u);
		return u;
	}
}
using namespace SGT;
void dfs1(int u,int f){
	dfn[u]=++now;
	fa[u][0]=f;
	for(int i=1;i<=L;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int v:g[u])if(v!=f)dfs1(v,u);
}
void dfs2(int u,int f){
	for(int v:g[u])if(v!=f){
		dfs2(v,u);
		rt[u]=merge(rt[u],rt[v],1,N);
	}
	ans[u]=a[rt[u]];
	if(!sum[rt[u]])ans[u]=0;
}
int lca(int u,int v){
	if(u==v)return u;
	if(dfn[u]>dfn[v])swap(u,v);
	for(int i=L;i>=0;i--)if(dfn[fa[v][i]]>dfn[u])v=fa[v][i];
	return fa[v][0];
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].pb(v),g[v].pb(u);
	}
	dfs1(1,0);
	for(int i=1;i<=q;i++){
		int u,v,x,l;
		cin>>u>>v>>x;
		l=lca(u,v);
		update(rt[u],1,N,x,1),update(rt[v],1,N,x,1);
		update(rt[l],1,N,x,-1),update(rt[fa[l][0]],1,N,x,-1);
	}
	dfs2(1,0);
	for(int i=1;i<=n;i++)cout<<ans[i]<<'\n';
}

DSU on tree

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1e6;
int n,m,now,mx,mn,l[N+5],r[N+5],id[N+5],h[N+5],dep[N+5],sz[N+5],cnt[N+5],ans[N+5];
vector<int> g[N+5];
void dfs1(int u,int f){
	l[u]=++now,id[now]=u,h[u]=0,dep[u]=dep[f]+1,sz[u]=1;
	for(int v:g[u])if(v!=f){
		dfs1(v,u);
		if(sz[h[u]]<sz[v])h[u]=v;
		sz[u]+=sz[v];
	}
	r[u]=now;
}
void add(int u,int d){
	int x=dep[u],&y=cnt[x];
	y+=d;
	if(mx<y)mx=y,mn=x;
	else if(mx==y)mn=min(mn,x);
}
void upd(int u,int d){for(int i=l[u];i<=r[u];i++)add(id[i],d);}
void dfs2(int u,int f){
	for(int v:g[u])if(v!=f&&v!=h[u])dfs2(v,u),upd(v,-1),mx=mn=0;
	if(h[u])dfs2(h[u],u);
	add(u,1);
	for(int v:g[u])if(v!=f&&v!=h[u])upd(v,1);
	ans[u]=mn-dep[u];
}
int main(){
	n=in();
	for(int i=1;i<n;i++){
		int u=in(),v=in();
		g[u].pb(v),g[v].pb(u);
	}
	dfs1(1,0),dfs2(1,0);
	for(int i=1;i<=n;i++)outln(ans[i]);
	return 0;
}

树上K级祖先(长链剖分)

#include<bits/stdc++.h>
#define int long long
#define uint unsigned
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=500005;
int n,q,r,h[N],dep[N],low[N],top[N],fa[N][25];
uint s;
vector<int>g[N],up[N],dn[N];
uint get(){
	s^=s<<13,s^=s>>17,s^=s<<5;
	return s;
}
void dfs1(int u,int f){
	dep[u]=low[u]=dep[f]+1,fa[u][0]=f;
	for(int i=1;i<=20;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int v:g[u]){
		dfs1(v,u);
		if(low[u]<low[v])h[u]=v,low[u]=low[v];
	}
}
void dfs2(int u,int p){
	top[u]=p;
	if(u==p){
		int l=low[u]-dep[u];
		for(int i=0,j=u;i<=l;i++,j=fa[j][0])up[u].pb(j);
		for(int i=0,j=u;i<=l;i++,j=h[j])dn[u].pb(j);
	}
	if(h[u])dfs2(h[u],p);
	for(int v:g[u])if(v!=h[u])dfs2(v,v);
}
int find(int u,int k){
	if(!k)return u;
	int l=__lg(k);
	u=fa[u][l],k-=(1<<l)+dep[u]-dep[top[u]],u=top[u];
	return k>=0?up[u][k]:dn[u][-k];
}
signed main(){
	n=in(),q=in(),s=in();
	for(int i=1;i<=n;i++)g[in()].pb(i);
	dfs1(r=g[0][0],0),dfs2(r,r);
	int lst=0,ans=0;
	for(int t=1;t<=q;t++){
		int u=(get()^lst)%n+1,k=(get()^lst)%dep[u];
		lst=find(u,k),ans^=t*lst;
	}
	out(ans);
	return 0;
}

虚树

#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=2.5e5,M=5e5,L=20,inf=1e10;
int n,q,m,now,a[N+5],dfn[N+5],fa[N+5][L+5],mn[N+5][L+5];
bool p[N+5];
vector<pii> g[N+5];
bool cmp(int x,int y){return dfn[x]<dfn[y];}
void dfs(int u,int f){
	dfn[u]=++now,fa[u][0]=f;
	for(int i=1;i<=L;i++)fa[u][i]=fa[fa[u][i-1]][i-1],mn[u][i]=min(mn[u][i-1],mn[fa[u][i-1]][i-1]);
	for(auto [v,w]:g[u])if(v!=f)mn[v][0]=w,dfs(v,u);
}
inline int lca(int u,int v){
	if(u==v)return u;
	if(dfn[u]>dfn[v])swap(u,v);
	for(int i=L;i>=0;i--)if(dfn[fa[v][i]]>dfn[u])v=fa[v][i];
	return fa[v][0];
}
inline int dis(int u,int f){
	if(u==f)return 0;
	int ret=inf;
	for(int i=L;i>=0;i--)if(dfn[fa[u][i]]>=dfn[f])ret=min(ret,mn[u][i]),u=fa[u][i];
	return ret;
}
namespace VT{
	int tot,b[M+5];
	vector<pii> g[N+5];
	inline void build(){
		sort(a+1,a+m+1,cmp);
		tot=0;
		for(int i=1;i<m;i++)b[++tot]=a[i],b[++tot]=lca(a[i],a[i+1]);
		b[++tot]=a[m],b[++tot]=1;
		sort(b+1,b+tot+1,cmp);
		tot=unique(b+1,b+tot+1)-b-1;
		for(int i=1;i<tot;i++){
			int l=lca(b[i],b[i+1]);
			g[l].pb({b[i+1],dis(b[i+1],l)});
		}
	}
	int dfs(int u){
		int ret=0;
		for(auto [v,w]:g[u]){
			int x=dfs(v);
			if(p[v])ret+=w;
			else ret+=min(w,x);
		}
		g[u].clear();
		return ret;
	}
}
signed main(){
	n=in();
	for(int i=1;i<n;i++){
		int u=in(),v=in(),w=in();
		g[u].pb({v,w}),g[v].pb({u,w});
	}
	dfs(1,0);
	q=in();
	while(q--){
		m=in();
		for(int i=1;i<=m;i++)a[i]=in(),p[a[i]]=1;
		VT::build();
		outln(VT::dfs(1));
		for(int i=1;i<=m;i++)p[a[i]]=0;
	}
	return 0;
}

点分治

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
#define gc getchar
#define pc putchar
#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=10005,M=10000005;
int n,m,q,rt,mn,W,k[N],dis[N],siz[N],ans[N],cnt[M];
bool vis[N];
vector< array<int,2> > g[N];
void dfs1(int u,int f,int tot){
	int mx=0;
	siz[u]=1;
	for(auto [v,w]:g[u])if(v!=f&&!vis[v]){
		dfs1(v,u,tot);
		siz[u]+=siz[v];
		mx=max(mx,siz[v]);
	}
	mx=max(mx,tot-siz[u]);
	if(mn>mx)rt=u,mn=mx;
}
void dfs2(int u,int f,int now){
	if(now>W)return;
	dis[++m]=now;
	for(auto [v,w]:g[u])if(v!=f&&!vis[v])dfs2(v,u,now+w);
}
void calc(int opt){
	sort(dis+1,dis+m+1);
	for(int i=1;i<=m;i++){
		for(int j=1;j<=q;j++)if(k[j]>=dis[i])ans[j]+=opt*cnt[k[j]-dis[i]];
		cnt[dis[i]]++;
	}
	for(int i=1;i<=m;i++)cnt[dis[i]]--;
}
void solve(int u,int tot){
	rt=u,mn=tot-1,dfs1(u,0,tot);
	vis[rt]=1,m=0,dfs2(rt,0,0);
	calc(1);
	for(auto [v,w]:g[rt])if(!vis[v])m=0,dfs2(v,rt,w),calc(-1);
	for(auto [v,w]:g[rt])if(!vis[v])solve(v,siz[v]);
}
int main(){
	n=in(),q=in();
	for(int i=1;i<n;i++){
		int u=in(),v=in(),w=in();
		g[u].pb({v,w}),g[v].pb({u,w});
	}
	for(int i=1;i<=q;i++)k[i]=in(),W=max(W,k[i]);
	solve(1,n);
	for(int i=1;i<=q;i++)ps(ans[i]?"AYE":"NAY");
}

树链剖分

#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define ls (k<<1)
#define rs (ls|1)
#define lm ((l+r)>>1)
#define rm (lm+1)
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1e5+5;
int n,q,r,p,tot,a[N],b[N],h[N],fa[N],siz[N],dfn[N],top[N];
vector<int> g[N];
void A(int &x,int y){x=(x+y)%p;}
namespace SGT{
	const int M=N<<2;
	int sum[M],tag[M];
	void adt(int k,int l,int r,int x){A(sum[k],(r-l+1)*x%p),A(tag[k],x);}
	void pushup(int k){sum[k]=(sum[ls]+sum[rs])%p;}
	void pushdown(int k,int l,int r){int &x=tag[k];adt(ls,l,lm,x),adt(rs,rm,r,x),x=0;}
	void build(int k,int l,int r){
		if(l==r){sum[k]=b[l];return;}
		build(ls,l,lm),build(rs,rm,r);
		pushup(k);
	}
	void modify(int k,int l,int r,int s,int t,int x){
		if(l>t||r<s)return;
		if(l>=s&&r<=t){adt(k,l,r,x);return;}
		pushdown(k,l,r);
		modify(ls,l,lm,s,t,x),modify(rs,rm,r,s,t,x);
		pushup(k);
	}
	int query(int k,int l,int r,int s,int t){
		if(l>t||r<s)return 0;
		if(l>=s&&r<=t)return sum[k];
		pushdown(k,l,r);
		return (query(ls,l,lm,s,t)+query(rs,rm,r,s,t))%p;
	}
}
using namespace SGT;
void dfs1(int u,int f){
	siz[u]=1,fa[u]=f;
	for(int v:g[u])if(v!=f){
		dfs1(v,u),siz[u]+=siz[v];
		if(siz[v]>siz[h[u]])h[u]=v;
	}
}
void dfs2(int u,int t){
	b[dfn[u]=++tot]=a[u],top[u]=t;
    if(h[u])dfs2(h[u],t);
    for(int v:g[u])if(v!=fa[u]&&v!=h[u])dfs2(v,v);
}
void q1(int u,int v,int x){
	while(top[u]!=top[v]){
		if(dfn[top[u]]>dfn[top[v]])swap(u,v);
		modify(1,1,n,dfn[top[v]],dfn[v],x);
		v=fa[top[v]];
	}
	if(dfn[u]>dfn[v])swap(u,v);
	modify(1,1,n,dfn[u],dfn[v],x);
}
int q2(int u,int v){
	int x=0;
	while(top[u]!=top[v]){
		if(dfn[top[u]]>dfn[top[v]])swap(u,v);
		A(x,query(1,1,n,dfn[top[v]],dfn[v]));
		v=fa[top[v]];
	}
	if(dfn[u]>dfn[v])swap(u,v);
	A(x,query(1,1,n,dfn[u],dfn[v]));
	return x;
}
void q3(int u,int x){modify(1,1,n,dfn[u],dfn[u]+siz[u]-1,x);}
int q4(int u){return query(1,1,n,dfn[u],dfn[u]+siz[u]-1);}
signed main(){
	n=in(),q=in(),r=in(),p=in();
	for(int i=1;i<=n;i++)a[i]=in()%p;
	for(int i=1;i<n;i++){
		int u=in(),v=in();
		g[u].pb(v),g[v].pb(u);
	}
	dfs1(r,0),dfs2(r,r),build(1,1,n);
	while(q--){
		int opt=in(),x,y,z;
		if(opt==1)x=in(),y=in(),z=in(),q1(x,y,z);
		if(opt==2)x=in(),y=in(),outln(q2(x,y));
		if(opt==3)x=in(),y=in(),q3(x,y);
		if(opt==4)x=in(),outln(q4(x));
	}
	return 0;
}

数论

线性基

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=50;
int n;
namespace Bas{
    int b[N];
    void ins(int x){
        for(int i=49;i>=0;i--)if(x>>i&1){
            if(!b[i]){b[i]=x;return;}
            x^=b[i];
        }
    }
    int ask(int x){
        for(int i=49;i>=0;i--)if((x^b[i])>x)x^=b[i];
        return x;
    }
}
using namespace Bas;
signed main(){
    n=in();
    for(int i=1;i<=n;i++)ins(in());
    out(ask(0));
	return 0;
}

Lucas

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int t,n,m,p,inv[N],fac[N],ifac[N];
int C(int x,int y){return x>=y?fac[x]*ifac[x-y]%p*ifac[y]%p:0;}
int L(int x,int y){return y?L(x/p,y/p)*C(x%p,y%p)%p:1;}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>t;
	while(t--){
		cin>>n>>m>>p;
		inv[0]=inv[1]=fac[0]=ifac[0]=1;
		for(int i=2;i<p;i++)inv[i]=inv[p%i]*(p-p/i)%p;
		for(int i=1;i<p;i++)fac[i]=fac[i-1]*i%p;
		for(int i=1;i<p;i++)ifac[i]=ifac[i-1]*inv[i]%p;
		cout<<L(n+m,n)<<'\n';
	}
	return 0;
}

BSGS

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace IO{
#define gc getchar
#define pc putchar
#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
int p,q,x,y;
unordered_map<int,int> mp;
int bsgs(){
	if(y==1)return 0;
	mp[y]=0;
	for(int i=1,j=x*y%p;i<q;i++,j=j*x%p)mp[j]=i;
	int pw=1;
	for(int i=1;i<=q;i++)pw=pw*x%p;
	for(int i=1,j=pw;i<=q;i++,j=j*pw%p)if(mp.count(j))return i*q-mp[j];
	return -1;
}
signed main(){
	p=in(),q=ceil(sqrt(p)),x=in(),y=in();
	int ans=bsgs();
	if(~ans)out(ans);
	else ps("no solution");
	return 0;
}

DS

线段树

标记永久化

#include<bits/stdc++.h>
#define int long long
#define ls (k<<1)
#define rs (ls|1)
#define lm ((l+r)>>1)
#define rm (lm+1)
using namespace std;
const int N=1e5+5;
int n,q,a[N];
namespace SGT{
	const int M=N<<2;
	int sum[M],tag[M];
	void pushup(int k,int l,int r){sum[k]=sum[ls]+sum[rs]+(r-l+1)*tag[k];}
	void build(int k,int l,int r){
		if(l==r){sum[k]=a[l];return;}
		build(ls,l,lm),build(rs,rm,r);
		pushup(k,l,r);
	}
	void modify(int k,int l,int r,int s,int t,int x){
		if(l>t||r<s)return;
		if(l>=s&&r<=t){sum[k]+=(r-l+1)*x,tag[k]+=x;return;}
		modify(ls,l,lm,s,t,x),modify(rs,rm,r,s,t,x);
		pushup(k,l,r);
	}
	int query(int k,int l,int r,int s,int t,int x){
		if(l>t||r<s)return 0;
		if(l>=s&&r<=t)return sum[k]+(r-l+1)*x;
		return query(ls,l,lm,s,t,x+tag[k])+query(rs,rm,r,s,t,x+tag[k]);
	}
}
using namespace SGT;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(1,1,n);
	while(q--){
		int op,l,r,x;
		cin>>op;
		if(op==1)cin>>l>>r>>x,modify(1,1,n,l,r,x);
		if(op==2)cin>>l>>r,cout<<query(1,1,n,l,r,0)<<'\n';
	}
}

可持久化数组

#include<bits/stdc++.h>
#define int long long
#define lm ((l+r)>>1)
#define rm (lm+1)
using namespace std;
const int N=1e6+5;
int n,q,a[N];
namespace SGT{
	const int M=N*25;
	int tot,rt[N],ls[M],rs[M],val[M];
	void build(int &k,int l,int r){
		if(!k)k=++tot;
		if(l==r){val[k]=a[l];return;}
		build(ls[k],l,lm),build(rs[k],rm,r);
	}
	void update(int &k,int l,int r,int x,int y){
		if(l>x||r<x)return;
		tot++,ls[tot]=ls[k],rs[tot]=rs[k],k=tot;
		if(l==r){val[k]=y;return;}
		update(ls[k],l,lm,x,y),update(rs[k],rm,r,x,y);
	}
	int query(int k,int l,int r,int x){
		if(l>x||r<x)return 0;
		if(l==r)return val[k];
		return query(ls[k],l,lm,x)+query(rs[k],rm,r,x);
	}
}
using namespace SGT;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(rt[0],1,n);
	for(int i=1;i<=q;i++){
		int v,op,x,y;
		cin>>v>>op;
		if(op==1)cin>>x>>y,update(rt[i]=rt[v],1,n,x,y);
		if(op==2)cin>>x,cout<<query(rt[i]=rt[v],1,n,x)<<'\n';
	}
}

静态区间第k小

#include<bits/stdc++.h>
#define lm ((l+r)>>1)
#define rm (lm+1)
using namespace std;
const int N=2e5+5;
int n,m,q,a[N],b[N];
namespace SGT{
	const int M=N*20;
	int tot,rt[N],ls[M],rs[M],cnt[M];
	void pushup(int k){cnt[k]=cnt[ls[k]]+cnt[rs[k]];}
	void update(int &k,int l,int r,int x){
		if(l>x||r<x)return;
		tot++,ls[tot]=ls[k],rs[tot]=rs[k],cnt[tot]=cnt[k],k=tot;
		if(l==r){cnt[k]++;return;}
		update(ls[k],l,lm,x),update(rs[k],rm,r,x);
		pushup(k);
	}
	int query(int u,int v,int l,int r,int x){
		if(l==r)return l;
		int y=cnt[ls[u]]-cnt[ls[v]];
		if(x<=y)return query(ls[u],ls[v],l,lm,x);
		else return query(rs[u],rs[v],rm,r,x-y);
	}
}
using namespace SGT;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
	sort(b+1,b+n+1),m=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
	for(int i=1;i<=n;i++)update(rt[i]=rt[i-1],1,m,a[i]);
	while(q--){
		int l,r,k;
		cin>>l>>r>>k;
		cout<<b[query(rt[r],rt[l-1],1,m,k)]<<'\n';
	}
}

李超线段树

#include<bits/stdc++.h>
#define int long long
#define ls (k<<1)
#define rs (ls|1)
#define lm ((l+r)>>1)
#define rm (lm+1)
using namespace std;
const int N=1e5+5,M=4e4,p=1e9;
const double eps=1e-9;
int n,m=39989,q;
double k[N],b[N];
double F(int x,int y){return k[y]*x+b[y];}
bool cmp(int x,int y,int z){return (abs(F(x,y)-F(x,z))<eps&&y<z)||F(x,y)-F(x,z)>eps;}
namespace SGT{
	int tag[M<<2];
	void ins(int k,int l,int r,int x){
		if(!tag[k]){tag[k]=x;return;}
		if(l==r){
			if(cmp(l,x,tag[k]))tag[k]=x;
			return;
		}
		if(cmp(lm,x,tag[k]))swap(x,tag[k]);
		if(cmp(l,x,tag[k]))ins(ls,l,lm,x);
		if(cmp(r,x,tag[k]))ins(rs,rm,r,x);
	}
	void ins(int k,int l,int r,int s,int t,int x){
		if(l>t||r<s)return;
		if(l>=s&&r<=t){ins(k,l,r,x);return;}
		ins(ls,l,lm,s,t,x),ins(rs,rm,r,s,t,x);
	}
	int query(int k,int l,int r,int x){
		int y=tag[k];
		if(l==r)return y;
		int z=x<=lm?query(ls,l,lm,x):query(rs,rm,r,x);
		return cmp(x,y,z)?y:z;
	}
}
using namespace SGT;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>q;
	int lst=0;
	while(q--){
		bool op;
		int x0,y0,x1,y1;
		cin>>op;
		if(op==0)cin>>x0,x0=(x0+lst-1)%m+1,cout<<(lst=query(1,1,m,x0))<<'\n';
		if(op==1){
			n++,cin>>x0>>y0>>x1>>y1,x0=(x0+lst-1)%m+1,y0=(y0+lst-1)%p+1,x1=(x1+lst-1)%m+1,y1=(y1+lst-1)%p+1;
			if(x0>x1)swap(x0,x1),swap(y0,y1);
			if(x0==x1)b[n]=max(y0,y1);
			else k[n]=1.0*(y0-y1)/(x0-x1),b[n]=y0-k[n]*x0;
			ins(1,1,m,x0,x1,n);
		}
	}
}

平衡树

Splay

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=2e5,inf=1e8;
int m;
namespace Splay{
	int tot,r,a[N+5],cnt[N+5],siz[N+5],s[N+5][2],f[N+5];
	void New(int val){tot++,a[tot]=val,cnt[tot]=1,siz[tot]=1;}
	void pushup(int x){siz[x]=siz[s[x][0]]+cnt[x]+siz[s[x][1]];}
	void init(){
		r=1,New(-inf),New(inf);
		s[r][1]=tot,f[tot]=r;
		pushup(r);
	}
	bool tp(int x){return s[f[x]][1]==x;}
	void rotate(int x){
		int y=f[x],z=f[y];
		bool t=tp(x);
		if(z)s[z][tp(y)]=x;
		f[x]=z;
		s[y][t]=s[x][!t],f[s[x][!t]]=y;
		s[x][!t]=y,f[y]=x;
		pushup(y),pushup(x);
	}
	void splay(int x,int g){
		while(f[x]!=g){
			int y=f[x],z=f[y];
			if(z!=g){
				if(tp(y)==tp(x))rotate(y);
				else rotate(x);
			}
			rotate(x);
		}
		if(!g)r=x;
	}
	int find(int x,int rnk){
		int now=siz[s[x][0]];
		if(rnk<=now)return find(s[x][0],rnk);
		if(rnk<=now+cnt[x])return x;
		return find(s[x][1],rnk-now-cnt[x]);
	}
	int pre(int x,int val,int ret){
		if(!x)return ret;
		if(a[x]<val)return pre(s[x][1],val,x);
		return pre(s[x][0],val,ret);
	}
	int suf(int x,int val,int ret){
		if(!x)return ret;
		if(a[x]>val)return suf(s[x][0],val,x);
		return suf(s[x][1],val,ret);
	}
	int rnk(int val){
		int p=pre(r,val,0),q=suf(r,val,0);
		splay(p,0),splay(q,p);
		return siz[s[p][0]]+cnt[p]+1;
	}
	void insert(int val){
		int p=pre(r,val,0),q=suf(r,val,0);
		splay(p,0),splay(q,p);
		if(s[q][0])cnt[s[q][0]]++,siz[s[q][0]]++;
		else{
			New(val);
			s[q][0]=tot,f[tot]=q;
		}
		pushup(q),pushup(p);
		splay(s[q][0],0);
	}
	void erase(int val){
		int p=pre(r,val,0),q=suf(r,val,0);
		splay(p,0),splay(q,p);
		if(!s[q][0])return;
		if(cnt[s[q][0]]>1)cnt[s[q][0]]--,siz[s[q][0]]--;
		else s[q][0]=0;
		pushup(q),pushup(p);
		if(s[q][0])splay(s[q][0],0);
	}
}
using namespace Splay;
int main(){
	init();
	m=in();
	while(m--){
		int opt=in(),x=in();
		if(opt==1)insert(x);
		if(opt==2)erase(x);
		if(opt==3)outln(rnk(x)-1);
		if(opt==4){
			int p=find(r,x+1);
			outln(a[p]),splay(p,0);
		}
		if(opt==5){
			int p=pre(r,x,0);
			if(a[p]!=-inf)outln(a[p]),splay(p,0);
		}
		if(opt==6){
			int p=suf(r,x,0);
			if(a[p]!=inf)outln(a[p]),splay(p,0);
		}
	}
}

FHQ Treap

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,q,rt,a[N],b[N],sz[N],s[N][2];
mt19937 rnd(random_device{}());
void New(int x){n++,a[n]=x,b[n]=rnd(),sz[n]=1;}
void pushup(int u){sz[u]=sz[s[u][0]]+sz[s[u][1]]+1;}
void split(int u,int x,int &l,int &r){
	if(!u){l=r=0;return;}
	if(a[u]<=x)l=u,split(s[u][1],x,s[u][1],r);
	else r=u,split(s[u][0],x,l,s[u][0]);
	pushup(u);
}
int merge(int u,int v){
	if(!u||!v)return u+v;
	if(b[u]<b[v]){s[u][1]=merge(s[u][1],v),pushup(u);return u;}
	s[v][0]=merge(u,s[v][0]),pushup(v);return v;
}
void ins(int x){
	int l,r;
	split(rt,x,l,r),New(x),rt=merge(merge(l,n),r);
}
void del(int x){
	int l,m,r;
	split(rt,x-1,l,m),split(m,x,m,r);
	m=merge(s[m][0],s[m][1]),rt=merge(merge(l,m),r);
}
int rnk(int x){
	int l,r,y;
	split(rt,x-1,l,r),y=sz[l]+1,rt=merge(l,r);
	return y;
}
int kth(int k){
	int u=rt;
	while(k!=sz[s[u][0]]+1){
		if(k<=sz[s[u][0]])u=s[u][0];
		else k-=sz[s[u][0]]+1,u=s[u][1];
	}
	return a[u];
}
int pre(int x){return kth(rnk(x)-1);}
int suf(int x){return kth(rnk(x+1));}
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>q;
	while(q--){
		int o,x;cin>>o>>x;
		if(o==1)ins(x);
		if(o==2)del(x);
		if(o==3)cout<<rnk(x)<<'\n';
		if(o==4)cout<<kth(x)<<'\n';
		if(o==5)cout<<pre(x)<<'\n';
		if(o==6)cout<<suf(x)<<'\n';
	}
}

字符串

KMP

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1000005;
int n,m,f[N];
char s[N],t[N];
int main(){
	scanf("%s%s",s+1,t+1);
	n=strlen(s+1),m=strlen(t+1);
	for(int i=2,j=0;i<=m;i++){
		while(j&&t[j+1]!=t[i])j=f[j];
		if(t[j+1]==t[i])j++;
		f[i]=j;
	}
	for(int i=1,j=0;i<=n;i++){
		while(j&&t[j+1]!=s[i])j=f[j];
		if(t[j+1]==s[i])j++;
		if(j==m)outln(i-m+1);
	}
	for(int i=1;i<=m;i++)outsp(f[i]);
}

AC自动机

#include<bits/stdc++.h>
using namespace std;
namespace IO{
#define gc getchar
#define pc putchar
#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=2e6+5,W=26;
int n,a[N];
char s[N];
namespace ACAM{
	int tot,g[N][W],fa[N],ans[N],d[N];
	basic_string<int> h[N];
	void ins(int x){
		int u=0,m=strlen(s+1);
		for(int i=1;i<=m;i++){
			int &v=g[u][s[i]-'a'];
			if(!v)v=++tot;
			u=v;
		}
		a[x]=u;
	}
	void bfs(){
		queue<int> q;
		for(int x:g[0])if(x)q.push(x);
		while(!q.empty()){
			int u=q.front();q.pop(),h[fa[u]]+=u;
			for(int i=0;i<W;i++){
				int &v=g[u][i];
				if(v)fa[v]=g[fa[u]][i],q.push(v);
				else v=g[fa[u]][i];
			}
		}
	}
	void dfs(int u){for(int v:h[u])dfs(v),ans[u]+=ans[v];}
}
using namespace ACAM;
int main(){
	n=in();
	for(int i=1;i<=n;i++)scanf("%s",s+1),ins(i);
	bfs(),scanf("%s",s+1);
	int m=strlen(s+1);
	for(int i=1,u=0;i<=m;i++)u=g[u][s[i]-'a'],ans[u]++;
	dfs(0);
	for(int i=1;i<=n;i++)outln(ans[a[i]]);
	return 0;
}

Manancher

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=22000005;
int n,m,fa[N];
char s[N],t[N];
int main(){
	scanf("%s",s+1),n=strlen(s+1),m=n*2+1;
	t[0]='(',t[m]='|',t[m+1]=')';
	for(int i=1;i<=n;i++)t[i*2-1]='|',t[i*2]=s[i];
	int ans=0;
	for(int i=2,j=1,r=1;i<=m;i++){
		if(r>i)fa[i]=min(fa[j*2-i],r-i);
		while(t[i-fa[i]-1]==t[i+fa[i]+1])fa[i]++;
		if(r<i+fa[i])r=i+fa[i],j=i;
		ans=max(ans,fa[i]);
	}
  out(ans);
	return 0;
}

PAM

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=500005,M=26;
int n,lst;
char s[N];
namespace PAM{
	int tot=1,g[N][M],l[N],fa[N],c[N];
	int I(char x){return x-'a';}
	char C(int x){return x+'a';}
	int find(int x,int i){
		while(s[i-l[x]-1]!=s[i])x=fa[x];
		return x;
	}
	void insert(int i){
		int f=find(lst,i),&u=g[f][I(s[i])];
		if(!u){
			tot++;
			l[tot]=l[f]+2,fa[tot]=g[find(fa[f],i)][I(s[i])],c[tot]=c[fa[tot]]+1;
			u=tot;
		}
		lst=u;
	}
}
using namespace PAM;
int main(){
	scanf("%s",s+1),n=strlen(s+1);
	fa[0]=1,l[1]=-1;
	for(int i=1;i<=n;i++)s[i]=C((I(s[i])+c[lst])%M),insert(i),outsp(c[lst]);
	return 0;
}

SA

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1e6+5;
int n,m,b[N],sa[N],sb[N],rk[N],rk2[N];
char s[N];
void Sort(){
	for(int i=1;i<=m;i++)b[i]=0;
	for(int i=1;i<=n;i++)b[rk[i]]++;
	for(int i=1;i<=m;i++)b[i]+=b[i-1];
	for(int i=n;i>=1;i--)sa[b[rk[sb[i]]]--]=sb[i];
}
void SA(){
	for(int i=1;i<=n;i++)rk[i]=s[i],sb[i]=i;
    Sort();
	for(int l=1;l<=n;l<<=1){
		int x=0;
		for(int i=n-l+1;i<=n;i++)sb[++x]=i;
		for(int i=1;i<=n;i++)if(sa[i]>l)sb[++x]=sa[i]-l;
		Sort(),swap(rk,rk2);
		for(int i=1;i<=n;i++){
			int x=sa[i],y=sa[i-1];
			rk[x]=rk[y]+(rk2[x]!=rk2[y]||rk2[x+l]!=rk2[y+l]);
		}
		m=rk[sa[n]];
        if(m==n)return;
	}
}
int main(){
	scanf("%s",s+1),n=strlen(s+1),m='z';
	SA();
	for(int i=1;i<=n;i++)outsp(sa[i]);
	return 0;
}

SAM

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1e6+5;
int n;
long long ans;
char s[N];
namespace SAM{
	const int M=N<<1;
	int tot,lst,l[M],fa[M],sz[M],g[M][26];
	vector<int> h[M];
	void ins(int x){
		int u=++tot,p=lst;
		l[u]=l[p]+1,sz[u]=1,lst=u;
		for(;~p&&!g[p][x];p=fa[p])g[p][x]=u;
		if(!~p)fa[u]=0;
		else{
			int q=g[p][x];
			if(l[q]==l[p]+1)fa[u]=q;
			else{
				int v=++tot;
				fa[v]=fa[q],l[v]=l[p]+1;
				for(int i=0;i<26;i++)g[v][i]=g[q][i];
				for(;~p&&g[p][x]==q;p=fa[p])g[p][x]=v;
                fa[u]=fa[q]=v;
			}
		}
	}
	void dfs(int u){
		for(int v:h[u])dfs(v),sz[u]+=sz[v];
		if(sz[u]>1)ans=max(ans,1ll*sz[u]*l[u]);
	}
}
using namespace SAM;
int main(){
	scanf("%s",s+1),n=strlen(s+1);
	fa[0]=-1;
	for(int i=1;i<=n;i++)ins(s[i]-'a');
	for(int i=1;i<=tot;i++)h[fa[i]].pb(i);
	dfs(0),printf("%lld",ans);
	return 0;
}

GSAM

在线

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int n,m;
char s[N];
namespace GSAM{
	const int M=N<<1,W=26;
	int tot,lst,fa[M],l[M],g[M][W];
	int split(int x,int p){
		int q=g[p][x];
		if(l[q]==l[p]+1)return q;
		int v=++tot;l[v]=l[p]+1,fa[v]=fa[q];
		memcpy(g[v],g[q],sizeof(g[q]));
		for(;~p&&g[p][x]==q;p=fa[p])g[p][x]=v;
		return fa[q]=v;
	}
	int ins(int x){
		int p=lst;
		if(g[p][x])return split(x,p);
		int u=++tot;l[u]=l[p]+1;
		for(;~p&&!g[p][x];p=fa[p])g[p][x]=u;
		fa[u]=~p?split(x,p):0;
        return u;
	}
}
using namespace GSAM;
signed main(){
	fa[0]=-1,scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",s+1),m=strlen(s+1),lst=0;
		for(int j=1;j<=m;j++)lst=ins(s[j]-'a');
	}
	int ans=0;
	for(int i=1;i<=tot;i++)ans+=l[i]-l[fa[i]];
	printf("%lld\n%lld",ans,tot+1);
	return 0;
}

离线

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int n,m;
char s[N];
namespace GSAM{
	const int M=N<<1,W=26;
	int tot,fa[M],l[M],g[M][W];
	void ins(){
		int u=0;
		for(int i=1;i<=m;i++){
			int &v=g[u][s[i]-'a'];
			if(!v)v=++tot;
			u=v;
		}
	}
	void ins(int lst,int x){
		int u=g[lst][x],p=fa[lst];
		if(l[u])return;
		l[u]=l[lst]+1;
		for(;~p&&!g[p][x];p=fa[p])g[p][x]=u;
		if(!~p)fa[u]=0;
		else{
			int q=g[p][x];
			if(l[q]==l[p]+1)fa[u]=q;
			else{
				int v=++tot;
				l[v]=l[p]+1,fa[v]=fa[q];
				for(int i=0;i<W;i++)if(l[g[q][i]])g[v][i]=g[q][i];
				for(;~p&&g[p][x]==q;p=fa[p])g[p][x]=v;
				fa[u]=fa[q]=v;
			}
		}
	}
	void bfs(){
		queue<int> q;q.push(0);
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int i=0;i<W;i++){
				int v=g[u][i];
				if(v)ins(u,i),q.push(v);
			}
		}
	}
}
using namespace GSAM;
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%s",s+1),m=strlen(s+1),ins();
	fa[0]=-1,bfs();int ans=0;
	for(int i=1;i<=tot;i++)ans+=l[i]-l[fa[i]];
	printf("%lld\n%lld",ans,tot+1);
	return 0;
}

离线算法

莫队

普通莫队

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5,B=300;
int n,q,m,now,a[N],c[N],ans[N];
struct node{int l,r,i;}Q[N];
int I(int x){return (x-1)/B+1;}
bool cmp(node x,node y){return I(x.l)!=I(y.l)?x.l<y.l:x.r<y.r;}
void add(int x){int &y=c[a[x]];now-=y*y,y++,now+=y*y;}
void del(int x){int &y=c[a[x]];now-=y*y,y--,now+=y*y;}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=q;i++)cin>>Q[i].l>>Q[i].r,Q[i].i=i;
	sort(Q+1,Q+q+1,cmp);
	for(int i=1,L=1,R=0;i<=q;i++){
		int l=Q[i].l,r=Q[i].r,id=Q[i].i;
		while(L>l)add(--L);
		while(R<r)add(++R);
		while(L<l)del(L++);
		while(R>r)del(R--);
		ans[id]=now;
	}
	for(int i=1;i<=q;i++)cout<<ans[i]<<'\n';
}

带修莫队

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,B=3000;
int n,m,Q,Q2,now,a[N],blo[N],c[N],ans[N];
struct query{int l,r,t,id;}q[N];
pair<int,int> q2[N];
bool cmp(query x,query y){return blo[x.l]!=blo[y.l]?x.l<y.l:(blo[x.r]!=blo[y.r]?(blo[x.l]&1?x.r<y.r:x.r>y.r):(blo[x.r]&1?x.t<y.t:x.t>y.t));}
void add(int x){now+=!c[a[x]]++;}
void del(int x){now-=!--c[a[x]];}
void upd(int x,int i){
	auto& [u,w]=q2[x];
	if(u>=q[i].l&&u<=q[i].r)del(u),swap(a[u],w),add(u);
	else swap(a[u],w);
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)blo[i]=(i-1)/B+1;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=m;i++){
		char o;int x,y;cin>>o>>x>>y;
		if(o=='Q')q[++Q]={x,y,Q2,Q};
		if(o=='R')q2[++Q2]={x,y};
	}
	sort(q+1,q+Q+1,cmp);
	int L=1,R=0,T=0;
	for(int i=1;i<=Q;i++){
		int l=q[i].l,r=q[i].r,t=q[i].t;
		while(L>l)add(--L);
		while(R<r)add(++R);
		while(L<l)del(L++);
		while(R>r)del(R--);
		while(T<t)upd(++T,i);
		while(T>t)upd(T--,i);
		ans[q[i].id]=now;
	}
	for(int i=1;i<=Q;i++)cout<<ans[i]<<'\n';
}

树上带修莫队

#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1e5+5,M=N<<1,B=1500;
int n,m,q,Q1,Q2,tot,now,a[N],b[N],c[N],cnt[N],ans[N],I[N],O[N],E[M],blo[M],fa[N][20];
bool vis[M];
vector<int> g[N];
struct query{int u,v,l,r,t,id;}q1[N];
pair<int,int> q2[N];
bool cmp(query x,query y){return blo[x.l]!=blo[y.l]?x.l<y.l:(blo[x.r]!=blo[y.r]?(blo[x.l]&1?x.r<y.r:x.r>y.r):(blo[x.r]&1?x.t<y.t:x.t>y.t));}
void dfs(int u,int f){
	tot++,I[u]=tot,E[tot]=u,fa[u][0]=f;
	for(int i=1;i<=16;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int v:g[u])if(v!=f)dfs(v,u);
	tot++,O[u]=tot,E[tot]=u;
}
signed lca(int u,int v){
	if(u==v)return u;
	for(int i=16;i>=0;i--)if(I[fa[v][i]]>I[u])v=fa[v][i];
	return fa[v][0];
}
void mdf(int x){
	int y=c[x];vis[x]^=1;
	if(vis[x])now+=a[y]*b[++cnt[y]];
	else now-=a[y]*b[cnt[y]--];
}
void upd(int x){
	auto &[u,w]=q2[x];
	if(vis[u])mdf(u),swap(c[u],w),mdf(u);
	else swap(c[u],w);
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	for(int i=1;i<n;i++){int u,v;cin>>u>>v;g[u].pb(v),g[v].pb(u);}
	dfs(1,0);
	for(int i=1;i<=tot;i++)blo[i]=(i-1)/B+1;
	for(int i=1;i<=n;i++)cin>>c[i];
	for(int i=1;i<=q;i++){
		int o,x,y;
		cin>>o>>x>>y;
		if(o==0)q2[++Q2]={x,y};
		if(o==1){
			if(I[x]>I[y])swap(x,y);
			q1[++Q1]={x,y,lca(x,y)==x?I[x]:O[x],I[y],Q2,Q1};
		}
	}
	sort(q1+1,q1+Q1+1,cmp);
	int L=1,R=0,T=0;
	for(int i=1;i<=Q1;i++){
		int u=q1[i].u,v=q1[i].v,l=q1[i].l,r=q1[i].r,t=q1[i].t;
		while(L>l)mdf(E[--L]);
		while(R<r)mdf(E[++R]);
		while(L<l)mdf(E[L++]);
		while(R>r)mdf(E[R--]);
		while(T<t)upd(++T);
		while(T>t)upd(T--);
		int x=lca(u,v);
		if(x!=u&&x!=v)mdf(x);
		ans[q1[i].id]=now;
		if(x!=u&&x!=v)mdf(x);
	}
	for(int i=1;i<=Q1;i++)cout<<ans[i]<<'\n';
}

整体二分

#include<bits/stdc++.h>
#define vec vector<int>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=200005;
int n,m,tot,a[N],b[N],t[N],ans[N];
struct query{int l,r,k;}q[N];
int lb(int x){return x&-x;}
void add(int x,int y){for(int i=x;i<=n;i+=lb(i))t[i]+=y;}
int sum(int x){int ret=0;for(int i=x;i>=1;i-=lb(i))ret+=t[i];return ret;}
void solve(int L,int R,vec &A,vec &Q){
	if(L==R){
		for(int i:Q)ans[i]=L;
		return;
	}
	int M=(L+R)>>1;
	vec Al,Ar,Ql,Qr;
	for(int i:A){
		if(a[i]<=M)Al.pb(i),add(i,1);
		else Ar.pb(i);
	}
	for(int i:Q){
		int x=sum(q[i].r)-sum(q[i].l-1);
		if(x>=q[i].k)Ql.pb(i);
		else Qr.pb(i),q[i].k-=x;
	}
	for(int i:Al)add(i,-1);
	solve(L,M,Al,Ql),solve(M+1,R,Ar,Qr);
}
int main(){
	n=in(),m=in();
	vec A,Q;
	for(int i=1;i<=n;i++)a[i]=b[i]=in(),A.pb(i);
	sort(b+1,b+n+1),tot=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
	for(int i=1;i<=m;i++)q[i]={in(),in(),in()},Q.pb(i);
	solve(1,tot,A,Q);
	for(int i=1;i<=m;i++)outln(b[ans[i]]);
	return 0;
}

多项式

FWT

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace IO{
#define gc getchar
#define pc putchar
#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=1<<17,p=998244353;
int n,A[N],B[N],a[N],b[N],c[N];
void add(int &x,int y){x=(x+y)%p;}
void reset(){for(int i=0;i<n;i++)a[i]=A[i],b[i]=B[i];}
void fwt1(int f[],int o){
	for(int i=1;i<n;i<<=1)
		for(int j=0;j<n;j+=i<<1)
			for(int k=0;k<i;k++)
				add(f[i+j+k],f[j+k]*o%p);
}
void fwt2(int f[],int o){
	for(int i=1;i<n;i<<=1)
		for(int j=0;j<n;j+=i<<1)
			for(int k=0;k<i;k++)
				add(f[j+k],f[i+j+k]*o%p);
}
void fwt3(int f[],int o){
	for(int i=1;i<n;i<<=1)
		for(int j=0;j<n;j+=i<<1)
			for(int k=0;k<i;k++){
				int x=f[j+k],y=f[i+j+k];
				f[j+k]=(x+y)%p*o%p,f[i+j+k]=(x-y+p)%p*o%p;
			}
}
void mul(){for(int i=0;i<n;i++)c[i]=a[i]*b[i]%p;}
void print(){for(int i=0;i<n;i++)outsp(c[i]);ps("");}
signed main(){
	n=1<<in();
	for(int i=0;i<n;i++)A[i]=in();
	for(int i=0;i<n;i++)B[i]=in();
	reset(),fwt1(a,1),fwt1(b,1),mul(),fwt1(c,p-1),print();
	reset(),fwt2(a,1),fwt2(b,1),mul(),fwt2(c,p-1),print();
	reset(),fwt3(a,1),fwt3(b,1),mul(),fwt3(c,(p+1)/2),print();
	return 0;
}

图论

连通性

强连通分量

#include<bits/stdc++.h>
#define vec vector<int>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=10005;
int n,m,cnt,tot,dfn[N],low[N];
bool vis[N];
vec g[N],a[N];
stack<int> s;
void tarjan(int u){
	dfn[u]=low[u]=++cnt;
	s.push(u),vis[u]=1;
	for(int v:g[u]){
		if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
		else if(vis[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		tot++;
		while(!s.empty()){
			int v=s.top();
			s.pop(),vis[v]=0;
			a[tot].pb(v);
			if(v==u)break;
		}
	}
}
int main(){
	n=in(),m=in();
	for(int i=1;i<=m;i++)g[in()].pb(in());
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
	for(int i=1;i<=tot;i++)sort(a[i].begin(),a[i].end());
	sort(a+1,a+tot+1,[&](vec x,vec y){return x[0]<y[0];});
	outln(tot);
	for(int i=1;i<=tot;i++,ps(""))for(int j:a[i])outsp(j);
	return 0;
}

边双连通分量

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=500005;
int n,m,k,tot,dfn[N],low[N];
stack<int> s;
vector<int> h[N];
vector< pair<int,int> > g[N];
void dfs(int u,int i){
	dfn[u]=low[u]=++tot,s.push(u);
	for(auto [v,j]:g[u])if(j!=i){
		if(!dfn[v])dfs(v,j),low[u]=min(low[u],low[v]);
		else low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		++k;
		while(s.top()!=u)h[k].pb(s.top()),s.pop();
		h[k].pb(u),s.pop();
	}
}
int main(){
	n=in(),m=in();
	for(int i=1;i<=m;i++){
		int u=in(),v=in();
		g[u].pb({v,i}),g[v].pb({u,i});
	}
	for(int i=1;i<=n;i++)if(!dfn[i])dfs(i,0);
    outln(k);
    for(int i=1;i<=k;i++,ps("")){
        outsp(h[i].size());
        for(int u:h[i])outsp(u);
    }
	return 0;
}

割点

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=20005;
int n,m,tot,cnt,dfn[N],low[N];
bool cut[N];
vector<int> g[N];
void dfs(int u,int f){
	dfn[u]=low[u]=++tot;
	int s=0;
	for(int v:g[u])if(v!=f){
		if(!dfn[v]){
			dfs(v,u),s++,low[u]=min(low[u],low[v]);
			if(f&&low[v]>=dfn[u])cnt+=!cut[u],cut[u]=1;
		}
		else low[u]=min(low[u],dfn[v]);
	}
	if(!f&&s>1)cnt+=!cut[u],cut[u]=1;
}
int main(){
	n=in(),m=in();
	for(int i=1;i<=m;i++){
		int u=in(),v=in();
		g[u].pb(v),g[v].pb(u);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])dfs(i,0);
	outln(cnt);
	for(int i=1;i<=n;i++)if(cut[i])outsp(i);
	return 0;
}

点双连通分量

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO{
	#define gc getchar
	#define pc putchar
	#define ps puts
	inline int in(){
		int x=0,f=1;
		char c=gc();
		for(;!isdigit(c);c=gc())if(c=='-')f=-1;
		for(;isdigit(c);c=gc())x=x*10+(c-'0');
		return x*f;
	}
	inline void out(int x){
		if(x<0)pc('-'),x=-x;
		if(x>=10)out(x/10);
		pc(x%10+'0');
	}
	inline void outsp(int x){out(x),pc(' ');}
	inline void outln(int x){out(x),ps("");}
}
using namespace IO;
const int N=5e5+5;
int n,m,k,tot,top,s[N],dfn[N],low[N];
vector<int> g[N],h[N];
void dfs(int u,int f){
	dfn[u]=low[u]=++tot,s[++top]=u;
	for(int v:g[u]){
		if(!dfn[v])dfs(v,u),low[u]=min(low[u],low[v]);
		else low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[f]){
		k++;
		do{h[k].pb(s[top--]);}while(s[top+1]!=u);
		h[k].pb(f);
	}
	if(!f&&g[u].empty())h[++k].pb(u);
}
int main(){
	n=in(),m=in();
	for(int i=1;i<=m;i++){
		int u=in(),v=in();
		if(u!=v)g[u].pb(v),g[v].pb(u);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])top=0,dfs(i,0);
	outln(k);
	for(int i=1;i<=k;i++,ps("")){
		outsp(h[i].size());
		for(int u:h[i])outsp(u);
	}
	return 0;
}
posted @ 2026-10-08 11:06  Lqs314  阅读(10)  评论(0)    收藏  举报