模板整理

2019/05/12 20:13
阅读数 19

未附加题目链接的板子均为核心代码。

最大流

void addedge(int u, int v, int w) //tot=1
{
	nxt[++tot]=head[u],head[u]=tot,to[tot]=v,wei[tot]=w;
	nxt[++tot]=head[v],head[v]=tot,to[tot]=u,wei[tot]=0;
}
bool bfs()
{
	memset(lev,-1,sizeof(lev));
	int l=0,r=0;
	q[0]=s; lev[s]=1;
	while(l<=r)
	{
		int u=q[l++];
		for(int e=head[u];e;e=nxt[e])
			if(lev[to[e]]==-1&&wei[e])
			{
				lev[to[e]]=lev[u]+1;
				if(to[e]==t) return true;
				q[++r]=to[e];
			}
	}
	return false;
}
int dfs(int u, int mx)
{
	if(u==t) return mx;
	int l=mx;
	for(int e=head[u];e&&l;e=nxt[e])
		if(lev[to[e]]==lev[u]+1&&wei[e]>0)
		{
			int f=dfs(to[e],min(l,wei[e]));
			if(!f) lev[to[e]]=-1;
			l-=f,wei[e]-=f,wei[e^1]+=f;
		}
	return mx-l;
}

最小费用流

void addedge(int u, int v, int w, int c)
{
	nxt[++tot]=head[u],head[u]=tot,to[tot]=v,wei[tot]=w,cost[tot]=c;
	nxt[++tot]=head[v],head[v]=tot,to[tot]=u,wei[tot]=0,cost[tot]=-c;
}
bool spfa()
{
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=t;++i) dis[i]=inf;
	queue<int> q;
	q.push(t),dis[t]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop(), vis[u]=false;
		for(int e=head[u];e;e=nxt[e])
			if(wei[e^1]&&dis[to[e]]>dis[u]-cost[e])
			{
				dis[to[e]]=dis[u]-cost[e];
				if(!vis[to[e]]) vis[to[e]]=true,q.push(to[e]);
			}
	}
	return dis[s]!=inf;
}
int dfs(int u, int mx)
{
	vis[u]=true;
	if(u==t) return mx;
	int l=mx;
	for(int e=head[u];e&&l;e=nxt[e])
		if(!vis[to[e]]&&wei[e]>0&&dis[to[e]]==dis[u]-cost[e])
		{
			int f=dfs(to[e],min(l,wei[e]));
			ans+=f*cost[e];
			l-=f,wei[e]-=f,wei[e^1]+=f;
		}
	return mx-l;
}

LOJ104 普通平衡树

#include<cstdio>
namespace io {
	const int SIZE=(1<<21)+1;
	char ibuf[SIZE],*iS,*iT,c; int qr;
#define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
	inline int gi (){
		int x=0,f=1;
		for(c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
		for(;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15); return x*f;
	}
} using io::gi;
const int N=200005,inf=1<<30;
int fa[N],ch[N][2],size[N],val[N],mp[N],cnt[N],t,rt;
void pushup(int x) {
	size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];
}
void rotate(int x)
{
	int y=fa[x],z=fa[y];
	int k=ch[y][1]==x,w=ch[x][!k];
	ch[z][ch[z][1]==y]=x;
	ch[x][!k]=y,ch[y][k]=w;
	fa[w]=y,fa[y]=x,fa[x]=z;
	pushup(y),pushup(x);
}
void splay(int x, int k)
{
	while(fa[x]!=k)
	{
		int y=fa[x],z=fa[y];
		if(z!=k) (ch[z][1]==y)^(ch[y][1]==x)?rotate(x):rotate(y);
		rotate(x);
	}
	pushup(x);
	if(!k) rt=x;
}
void insert(int x)
{
	int u=rt,f=0;
	while(u&&val[u]!=x) f=u,u=ch[u][x>val[u]];
	if(u) ++cnt[u];
	else
	{
		u=++t,val[u]=x,cnt[u]=size[u]=1,mp[t]=u;
		if(f) ch[f][x>val[f]]=u,fa[u]=f;
	}
	splay(u,0);
}
int findk(int x)
{
	int u=rt;
	while(true)
	{
		if(x>size[ch[u][0]]+cnt[u]) x-=size[ch[u][0]]+cnt[u],u=ch[u][1];
		else if(x<=size[ch[u][0]]) u=ch[u][0];
		else return val[u];
	}
}
void makert(int x)
{
	int u=rt;
	while(ch[u][x>val[u]]&&val[u]!=x) u=ch[u][x>val[u]];
	splay(u,0);
}
int getrk(int x)
{
	int u=rt,rnk=0;
	while(u)
	{
		if(x<val[u]) u=ch[u][0];
		else
		{
			rnk+=size[ch[u][0]];
			if(val[u]==x)
			{
				splay(u,0);
				return rnk+1;
			}
			rnk+=cnt[u];
			u=ch[u][1];
		}
	}
	return rnk;
}
int findpre(int x)
{
	makert(x);
	if(val[rt]<x) return rt;
	int u=ch[rt][0];
	while(ch[u][1])u=ch[u][1];
	return u;
}
int findnxt(int x)
{
	makert(x);
	if(val[rt]>x) return rt;
	int u=ch[rt][1];
	while(ch[u][0])u=ch[u][0];
	return u;
}
void remove(int u)
{
	int x=findpre(u),y=findnxt(u);
	splay(x,0);
	if(y) splay(y,x);
	if(cnt[ch[y][0]]>1) --cnt[ch[y][0]],splay(ch[y][0],0);
	else ch[y][0]=0;
}
int main()
{
	int n=gi();
	insert(-inf),insert(inf);
	while(n--)
	{
		int op=gi(),x=gi();
		if(op==1) insert(x);
		if(op==2) remove(x);
		if(op==3) printf("%d\n",getrk(x)-1);
		if(op==4) printf("%d\n",findk(x+1));
		if(op==5) printf("%d\n",val[findpre(x)]);
		if(op==6) printf("%d\n",val[findnxt(x)]);
	}
}

LOJ105 文艺平衡树

#include<cstdio>
#include<algorithm>
inline int gi()
{
	char c; int x=0;
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
	return x;
}
const int N=100005;
int ch[N][2],fa[N],size[N],rev[N],a[N],val[N],rt,id,n,m;
void pushup(int x) {
	size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void pushdown(int x)
{
	if(!rev[x]) return ;
	if(ch[x][0]) rev[ch[x][0]]^=1;
	if(ch[x][1]) rev[ch[x][1]]^=1;
	std::swap(ch[x][0],ch[x][1]);
	rev[x]=0;
}
void rotate(int x)
{
	int y=fa[x],z=fa[y];
	int k=ch[y][1]==x,w=ch[x][!k];
	ch[z][ch[z][1]==y]=x,ch[x][!k]=y,ch[y][k]=w;
	fa[w]=y,fa[y]=x,fa[x]=z;
	pushup(y),pushup(x);
}
void splay(int x, int k)
{
	while(fa[x]!=k)
	{
		int y=fa[x],z=fa[y];
		pushdown(z),pushdown(y),pushdown(x);
		if(z!=k) (ch[z][1]==y)^(ch[y][1]==x)?rotate(x):rotate(y);
		rotate(x);
	}
	if(!k) rt=x;
}
void build(int& x, int l, int r, int f)
{
	if(l>r) return ;
	x=++id; int mid=l+r>>1;
	val[x]=a[mid],size[x]=1,fa[x]=f;
	build(ch[x][0],l,mid-1,x);
	build(ch[x][1],mid+1,r,x);
	pushup(x);
}
int findk(int k)
{
	int u=rt;
	while(true)
	{
		pushdown(u);
		if(size[ch[u][0]]+1==k) return u;
		if(k>size[ch[u][0]]+1) k-=size[ch[u][0]]+1,u=ch[u][1];
		else u=ch[u][0];
	}
}
int split(int x, int y)
{
	int l=findk(x),r=findk(y+2);
	splay(l,0),splay(r,l);
	return r;
}
void solve(int u)
{
	pushdown(u);
	if(ch[u][0]) solve(ch[u][0]);
	if(1<=val[u]&&val[u]<=n) printf("%d ",val[u]);
	if(ch[u][1]) solve(ch[u][1]);
}
int main()
{
	n=gi(),m=gi();
	for(int i=2;i<=n+2;++i) a[i]=i-1;
	build(rt,1,n+2,0);
	while(m--)
	{
		int l=gi(),r=gi();
		int x=split(l,r);
		rev[ch[x][0]]^=1;
	}
	solve(rt);
}

分治 NTT

void init(int x)
{
	for(m=1;m<=x;m<<=1,++l);
	for(int i=0;i<m;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
}
#define mul(x,y) (1ll*x*y%Mod)
namespace poly
{
	int r[N],a[N],b[N],w[N],iw[N],m,l;
	void init(int x)
	{
		for(m=1,l=0;m<=x;m<<=1,++l);
		for(int i=0;i<m;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
		int b=po(3,(Mod-1)/m),ib=po(b,Mod-2);
		w[m/2]=iw[m/2]=1;
		for(int i=1;i<m/2;++i) w[m/2+i]=mul(w[m/2+i-1],b),iw[m/2+i]=mul(iw[m/2+i-1],ib);
		for(int i=m/2-1;i;--i) w[i]=w[i<<1],iw[i]=iw[i<<1];
	}
	void ntt(int* a, int f)
	{
		for(int i=0;i<m;++i) if(i<r[i]) swap(a[i],a[r[i]]);
		for(int i=1,id=1;i<m;i<<=1,++id)
		{
			for(int j=0;j<m;j+=i<<1)
				for(int k=0;k<i;++k)
				{
					int x=a[j+k],y=mul((f==1?w[i+k]:iw[i+k]),a[i+j+k]);
					a[j+k]=(x+y>=Mod?x+y-Mod:x+y);
					a[i+j+k]=(x-y<0?x-y+Mod:x-y);
				}
		}
		if(f==-1)
		{
			int in=po(m,Mod-2);
			for(int i=0;i<m;++i) a[i]=mul(a[i],in);
		}
	}
	void cdqntt(int l, int r)
	{
		if(l==r)
		{
			if(!l) f[l]=1;
			return ;
		}
		int mid=l+r>>1;
		cdqntt(l,mid);
		for(int i=l;i<=mid;++i) a[i-l]=f[i];
		for(int i=1;i<=r-l+1;++i) b[i]=g[i];
		if(r-l+1<=85)
		{
			for(int i=0;i<=mid-l;++i)
				for(int j=max(1,mid-i-l+1);j<=r-l+1&&i+j+l<=r;++j) upd(f[i+j+l],mul(a[i],b[j]));
		}
		else
		{
			init(r-l);
			memset(a+(mid-l+1),0,sizeof(int)*(m-(mid-l+1)));
			memset(b+(r-l+2),0,sizeof(m-(r-l+2)));
			ntt(a,1),ntt(b,1);
			for(int i=0;i<m;++i) a[i]=mul(a[i],b[i]);
			ntt(a,-1);
			for(int i=mid+1;i<=r;++i) upd(f[i],a[i-l]);
		}
		cdqntt(mid+1,r);
	}
}

后缀排序

void Sort()
{
	memset(tm,0,sizeof(int)*(m+1));
	for(int i=1;i<=n;++i) ++tm[rk[i]];
	for(int i=1;i<=m;++i) tm[i]+=tm[i-1];
	for(int i=n;i>=1;--i) sa[tm[rk[se[i]]]--]=se[i];
}
void getsa()
{
	for(int i=1;i<=n;++i) rk[i]=s[i],se[i]=i;
	Sort();
	for(int h=1;h<=n;h<<=1)
	{
		int cnt=0;
		for(int i=n-h+1;i<=n;++i) se[++cnt]=i;
		for(int i=1;i<=n;++i) if(sa[i]>h) se[++cnt]=sa[i]-h;
		Sort();
		std::swap(rk,se);
		rk[sa[1]]=cnt=1;
		for(int i=2;i<=n;++i)
			rk[sa[i]]=(se[sa[i]]==se[sa[i-1]]&&se[sa[i]+h]==se[sa[i-1]+h])?cnt:++cnt;
		m=cnt;
		if(m>=n) break;
	}
	int k=0;
	for(int i=1;i<=n;++i)
	{
		if(k) --k;
		int j=sa[rk[i]-1];
		while(s[i+k]==s[j+k]) ++k;
		hei[rk[i]]=k;
	}
}

k 大异或和

void ins(ll a)
{
	for(int i=50;i>=0;i--)
	if((a>>i)&1ll) 
	{
		if(v[i]) a^=v[i];
		else {v[i]=a;return;}
	}
	if(!a) flag=1;
	return;
}
void check()
{
	for(int i=50;i>=0;i--)
	for(int j=i-1;j>=0;j--)
	if((v[i]>>j)&1) v[i]^=v[j];
	for(int i=50;i>=0;i--) cnt+=(v[i]>0);
}
ll query(ll k)
{
	if(k>(1ll<<cnt)) return -1;
	if(flag) k--;
	if(k==-1) return 0;
	ll res=0;
	for(int i=0;i<=50&&k;i++)
	if(v[i])
	{
		res^=(k&1)*v[i];
		k>>=1;
	}
	return res;
}

LCT

#define isnrt(x) (ch[fa[x]][0]==x||ch[fa[x]][1]==x)
void pushup(int x) { /*...*/ }
void pushdown(int x)
{
	if(rev[x])
	{
		rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
		swap(ch[x][0],ch[x][1]);
		rev[x]=0;
	}
}
void rotate(int x)
{
	int y=fa[x],z=fa[y];
	int k=ch[y][1]==x,w=ch[x][!k];
	if(isnrt(y)) ch[z][ch[z][1]==y]=x;
	ch[x][!k]=y,ch[y][k]=w;
	fa[w]=y,fa[y]=x,fa[x]=z;
	pushup(y),pushup(x);
}
void splay(int x)
{
	int y=x,tp=1; st[1]=y;
	while(isnrt(y)) st[++tp]=y=fa[y];
	while(tp) pushdown(st[tp--]);
	while(isnrt(x))
	{
		int y=fa[x],z=fa[y];
		if(isnrt(y)) (ch[z][1]==y)^(ch[y][1]==x)?rotate(x):rotate(y);
		rotate(x);
	}
	pushup(x); 
}
void access(int x) { int y=0; for(;x;y=x,x=fa[x]) splay(x),ch[x][1]=y,pushup(x); }
void makert(int x) { access(x),splay(x),rev[x]^=1; }
void link(int x, int y) { makert(x); fa[x]=y; }
void split(int x, int y) { makert(x),access(y),splay(y); }
void cut(int x, int y) { split(x,y); ch[y][0]=fa[x]=0; }

后缀自动机

orz wyj!

void extend(int c)
{
	int p=lst,np=++cnt;lst=np;
	len[np]=len[p]+1,size[np]=1;
	for(;p&&!ch[p][c];p=pre[p]) ch[p][c]=np;
	if(!p) {
		pre[np]=1;
		return ;
	}
	int q=ch[p][c];
	if(len[p]+1==len[q]) {
		pre[np]=q;
		return ;
	}
	int nq=++cnt;len[nq]=len[p]+1;
	memcpy(ch[nq],ch[q],sizeof(ch[q]));
	pre[nq]=pre[q],pre[q]=pre[np]=nq;
	for(;ch[p][c]==q;p=pre[p])ch[p][c]=nq;
}

高斯消元

void gauss(int n)
{
	for(int i=1;i<=n;++i)
	{
		int r=i;
		for(int j=i+1;j<=n;++j) if(fabs(a[r][i])<fabs(a[j][i])) r=j;
		if(r!=i) swap(a[i],a[r]);
		for(int j=n+1;j>=i;--j) a[i][j]/=a[i][i];
		for(int j=i+1;j<=n;++j)
			for(int k=n+1;k>=i;--k) a[j][k]-=a[j][i]*a[i][k];
	}
	ans[n]=a[n][n+1];
	for(int i=n-1;i;--i)
	{
		ans[i]=a[i][n+1];
		for(int j=i+1;j<=n;++j) ans[i]-=a[i][j]*ans[j];
	}
}

自然数幂和(拉格朗日插值)

int lagpow(ll n, int c)
{
	c+=2;
	inv[0]=inv[1]=1;
	for(int i=2;i<=c;++i) inv[i]=mul(Mod-Mod/i,inv[Mod%i]);
	for(int i=2;i<=c;++i) inv[i]=mul(inv[i],inv[i-1]);
	pre[0]=suf[c+1]=1;
	for(int i=1;i<=c;++i) pre[i]=mul(pre[i-1],(n-i)%Mod);
	for(int i=c;i>=1;--i) suf[i]=mul(suf[i+1],(n-i)%Mod);
	int sum=0,ans=0;
	for(int i=1;i<=c;++i)
	{
		sum=add(sum,po(i,c-2));
		int t=mul(mul(inv[i-1],inv[c-i]),mul(pre[i-1],suf[i+1]));
		t=mul(t,sum);
		ans=((c-i&1)?sub(ans,t):add(ans,t));
	}
	return ans;
}

[LOJ122]「强制在线」动态图连通性

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int N=5004;

int n,m,lst,vis[N],q[N];
vector<int>G[N];

bool bfs(int S,int T,int C)
{
	int ql,qr;
	ql=1;
	qr=0;
	q[++qr]=S;
	vis[S]=C;
	while(ql<=qr)
	{
		int u=q[ql++];
		for(auto v:G[u])
		{
			if(v==T)
				return true;
			if(vis[v]!=vis[u])
			{
				vis[v]=vis[u];
				q[++qr]=v;
			}
		}
	}
	return false;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1,opt,x,y; i<=m; i++)
	{
		scanf("%d%d%d",&opt,&x,&y);
		x^=lst;
		y^=lst;
		if(opt==0)
		{
			G[x].push_back(y);
			G[y].push_back(x);
		}
		if(opt==1)
		{
			for(auto p=G[x].begin(); p!=G[x].end(); ++p)
				if(*p==y){G[x].erase(p);break;}
			for(auto p=G[y].begin(); p!=G[y].end(); ++p)
				if(*p==x){G[y].erase(p);break;}
		}
		if(opt==2)
		{
			int e=bfs(x,y,i);
			puts(e?"Y":"N");
			lst=(e?x:y);
		}
	}
	return 0;
}
展开阅读全文
ntt
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部