模板

9 篇文章 1 订阅
1 篇文章 0 订阅

模板

现在距离 2019 C S P 2019CSP 2019CSP 不到 24 24 24 小时了,积攒了很多的模板,为了不发最后一片学术博客进行记录,还可以算是给萌新 O I OI OI 一个总结吧,(这是最后这几天敲的,可能不会很全,希望评论多给扩充,应该仅限于今天吧,明天就上刑场了)大佬们,都发说说纪念了,我就发个博客吧(嘻嘻)

搜索:

dfs:

void dfs()//深搜
{
    if() return ;//剪枝
    over()//枚举出所有情况
    {
        dfs();//再次dfs
    }
}

bfs:

void bfs//广搜
{
	Q.push();
    while(!Q.empty())
    {
    	int x=Q.frond();
    	for()//枚举出所有情况
    	{
            
			Q.push();
		}
		Q.pop();
	}
}

图论:

floyed:

void floyed()
{
	over(i,1,n) over(j,1,n) f[i][j]=ocean;
	over(i,1,n) f[i][i]=0;
	over(k,1,n) over(i,1,n) over(j,1,n)
	f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}

spfa(bfs版):

void spfa(int s)
{
	memset(d,0x3f,sizeof d);
	memset(v,0,sizeof v);
	queue<int>Q; Q.push(s); v[s]=1;d[s]=0;
	while(!Q.empty())
	{
		int x=Q.front();Q.pop();v[x]=0;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver,z=e[i].edge;
			if(d[y]>d[x]+z)
			{
				d[y]=d[x]+z;
				if(!v[y]) v[y]=1,Q.push(y);
			}
		}
	}
}

spfa(dfs版):

void spfa(int x)
{
    v[x]=1;
    for(int i=last[x];i;i=e[i].next)
    {
        int y=e[i].ver,z=e[i].edge;
        if(d[y]>d[x]+z)
        {
            d[y]=d[x]+z;
            if(v[y]) return ;
            if(!spfa(y)) return ;
        }
    }
    v[x]=0;
}

dijkstra:

priority_queue<pii,vector<pii>,greater<pii> > Q;
void dijkstra(int s)
{
	over(i,1,n) d[i]=ocean;
	memset(v,0,sizeof v);
	Q.push(mp(0,s)); d[s]=0;
	while(!Q.empty())
	{
		int x=Q.top().sec;Q.pop();
		if(v[x]) continue; v[x]=1;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver,z=e[i].edge;
			if(d[y]>d[x]+z)
			d[y]=d[x]+z,Q.push(mp(d[y],y));
		}
	}
}

tarjan:

void tarjan(int x)
{
	dfn[x]=low[x]=++deep; sta[++st]=x;
	for(int i=last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
		else if(!id[y]) low[x]=min(low[x],dfn[y]); 
	}
	if(dfn[x]==low[x])
	{
		id[x]=++cnt; 
		while(x^sta[st]) id[sta[st--]]=cnt;
		st--;
	}
}

并查集:

int get(int x)
{
    return x==fa[x]?x:fa[x]=get(fa[x]);
}
void incor(int x,int y)
{
    int xx=get(x),yy=get(y);
    if(xx!=yy) fa[xx]=yy;
}

kruskal:

void kruskal()
{
    sort(e+1,e+tot+1,cmp);
    over(i,1,tot)
    {
        int x=get(e[i].x),y=get(e[i].y);
        if(x==y) continue;
        ans+=e[i].edge;fa[x]=y;
        if(++cnt==n-1) break;
    }
}

二分图—匈牙利算法:

bool hgry(int x)
{
	over(i,1,n) if(!v[i]&&g[x][i])
	{
		v[i]=1;
		if(!pre[i]||hgry(pre[i]))
		{pre[i]=x;return 1;}
	}
}
	over(i,1,n)
	{
		memset(v,0,sizeof v);
		if(hgry(i)) ans++;
	}

LCA:

void dfs(int x,int f)
{
	fa[0][x]=f; deep[x]=deep[f]+1;
	for(int i=last[x];i;i=e[i].next)
	if(e[i].ver!=fa[0][x]) dfs(e[i].ver,x); 
}
int lca(int x,int y)
{
	if(deep[x]>deep[y]) swap(x,y);
	for(int d=deep[y]-deep[x],i=0;d;d>>=1,i++) if(d&1) y=fa[i][y];
	if(x==y) return x;
	for(int i=21;i>=0;--i) if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
	return fa[0][x]; 
}

欧拉路:

void dfs(int x)
{
	while(v[x].size())
	{
		int y=v[x].size()-1;
		int k=v[x][y];v[x].resize(y);dfs(k);
	}
	ans[++cnt]=x;
}
//注意反向建边,回溯输出 
//欧拉路:把所有边都走一遍不回到起点的 
//有向图:所有入度=出度 或  起点出度-入度=1,终点入度-出度=1 
//无向图:所有点偶数度 或 除了两个点为奇数度,其余为偶数度 
//输出路径可以用vector.resize()或栈

拓扑排序:

void topu() 
{
	queue<int>Q;
	over(i,1,n) if(!ru[i]) Q.push(i);
	while(!Q.empty())
	{
		int x=Q.front(); Q.pop();
		ans[++cnt]=x;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver; ru[y]--;
			if(!ru[y])Q.push(y);
		}
	}
	if(cnt!=n) puts("-1");
	else over(i,1,n) printf("%d ",ans[i]);
}

最短路记录路径:

void dijkstra(int s)
{
	over(i,1,n) d[i]=ocean;
	memset(v,0,sizeof v);
	Q.push(mp(0,s)); d[s]=0;
	while(!Q.empty())
	{
		int x=Q.top().sec;Q.pop();
		if(v[x]) continue; v[x]=1;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver,z=e[i].edge;
			if(d[y]>d[x]+z)
			d[y]=d[x]+z,pre[y]=x,Q.push(mp(d[y],y));
		}
	}
}
void print(int s,int t)
{
	if(d[t]==ocean) {printf("-1");return ;}
	for(int i=n;i!=s;i=pre[i]) ans[++cnt]=i; ans[++cnt]=1;
	lver(i,cnt,1) printf("%d ",ans[i]);
}

最短路路径计数:

void dijkstra(int s)
{
	over(i,1,n) d[i]=ocean;
	memset(v,0,sizeof v);
	Q.push(mp(0,s)); d[s]=0;
	while(!Q.empty())
	{
		int x=Q.top().sec;Q.pop();
		if(v[x]) continue; v[x]=1;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver,z=e[i].edge;
			if(d[y]==d[x]+z) cnt[y]=cnt[x]+cnt[y];
			if(d[y]>d[x]+z)	d[y]=d[x]+z,cnt[y]=cnt[x],Q.push(mp(d[y],y));
		}
	}
}
void spfa(int s)
{
	memset(d,0x3f,sizeof d);
	memset(v,0,sizeof v);
	queue<int>Q; Q.push(s); v[s]=1; d[s]=0;
	while(!Q.empty())
	{
		int x=Q.front(); Q.pop();v[x]=0;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].ver,z=e[i].edge;
			if(d[y]>d[x]+z){d[y]=d[x]+z; if(!v[y]) v[y]=1,Q.push(y);}
			if(d[y]==d[x]+z)  ans[y]=(ans[y]+=ans[x])%mod; 
		}
	}
}

割边:

void gb(int x,int fa)
{
	dfn[x]=low[x]=++deep;
	for(int i=last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y])
		{
			gd(y,x); low[x]=min(low[x],low[y]);
			if(dfn[x]<low[y])
			col[x]=col[x^1]=1;	
		}
		else if(y!=fa) low[x]=min(low[x],dfn[y]);
	}
}

割点:

void gd(int x,int fa)
{
	dfn[x]=low[x]=++deep; int flag=0;
	for(int i=last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(!dfn[y]) 
		{
			tarjan(y);
			low[x]=min(low[x],low[x]);
			if(low[y]>=dfn[x])
			{
				flag++;
				if(x!=root||flag>1) col[x]=1;
			}
		}
		else low[x]=min(low[x],dfn[y]);
	}
}

数论:

快速幂:

int ksm(int a,int b)
{
    int s=1;
   	while(b) 
    {
        if(b&1) s=s*a%mod;
        a=a*a%mod; b>>=1;   
    }
    return s;
}

线性求阶乘及阶乘逆元:

void xxqny()
{
	jc[0]=1; inv[0]=inv[1]=1;
	over(i,1,sea) jc[i]=jc[i-1]*i%mod;
	over(i,2,sea) inv[i]=mod-mod/i*inv[mod%i]%mod;
	over(i,2,sea) inv[i]=inv[i-1]*inv[i]%mod;
}

gcd:

int gcd(int x,int y)
{
	return !b?a:gcd(b,b%a);    
}

lcm:

int lcm(int x,int y)
{
    return x*y/gcd(x,y);
}

exgcd:

//是用来解线性同余方程 ax+by=c -> x=y(mod p) (同余符号)
//可以解出来其中一组解 
void exgcd(int x,int y)
{
	int s,int t;
	if(!b){x=0,y=1;return ;}
	s=exgcd(b,a%b,x,y);
	t=y;x=y;y=t-a/b*y;
	return s;
}
//求最小的正整数的解
	int t=gcd(a,b);
	if(c%t) printf("NO solution\n");
	a/=t,b/=t,c/=t;
	exgcd(a,b,x,y);
	x=((c*x)%b+b)%b;
	printf("%lld\n",x);

矩阵快速幂:

struct mrix{int mr[sea][sea];}a,b;
int n,k;
mrix mul(mrix a,mrix b)
{
	mrix s; memset(s.mr,0,sizeof s.mr);
	over(i,1,n) over(j,1,n) over(k,1,n)
	{
		s.mr[i][j]+=(a.mr[i][k]%mod)*(b.mr[i][k]%mod);
		s.mr[i][j]%=mod;
	}
	return s;
}
void ksm(int x)
{
	while(x)
	{
		if(x&1) a=mul(a,b);
		b=mul(b,b); x>>=1;
	}
}

线性筛:

void xxs()
{
	memset(v,sizeof v); 
	int cnt=0; v[1]=1; v[0]=1;
	over(i,2,n)
	{
		if(!v[i]) prim[cnt++]=i;
		for(int j=0;i<cnt&&i*prim[j]<=n;j++)
		{
			v[prim[j]*i]=1;
			if(i%prim[j]==0) break;
		}
	}
}

欧拉函数:

//欧拉函数:求一个数之前的互质对的个数 
void euler(int x)
{
	int s=x;
	for(int i=1;i*i<=x;i++) if(x%i==0)
	{
		s=s/i*(i-1);
		while(x%i==0) x/=i;
	}
	if(x!=1) s=s/x*(x-1);//可能会存在一个大于根号n的素因子
	return s;
}
void eulerycl()
{
	euler[1]=1;
	over(i,2,n) euler[i]=i;
	over(i,2,n)	if(euler[i]==i) for(int j=i;j<=n;j+=i)
	euler[j]=euler[j]/i*(i-1);
}

组合数:

int C(int x,int y)
{
    return jc[x]*inv[y]%mod*inv[x-y]%mod;
}

动态规划:

01背包:

over(i,1,n) lver(j,V,v[i])
if(j>=v[i]) f[j]=max(f[j],f[j-v[i]]+w[i]);
printf("%d\n",f[V]);

完全背包:

over(i,1,n)  over(j,v[i],V)
f[j]=max(f[j],f[j-v[i]]+w[i]);
printf("%d\n",f[V]);

数据结构:

初级数据结构:

栈:

//基础操作:
stack<int>st;
	st.empty();
	st.pop();
	st.push();
	st.top();
//单调栈:
over(i,1,n)
{
	while(top&&a[st[top]]<a[i]) top--;
	l[i]=st[top]; st[++top]=i;
}

队列:

//基础操作: 
	queue<int>Q;
	Q.empty(); 
	Q.pop();
	Q.front();
	Q.size();
	Q.back();
//单调队列:
int head=1,tail=0;
over(i,1,n) 
{
	while(tail>=head&&i-q[head]+1>m) head++;
	while(tail>=head&&a[i]>a[q[tail]]) tail--;
	q[++tail]=i;
	if(i>=m) cout<<a[q[h]]<<' ';
}

堆:

基础操作: 
priority_queue<int,vector<int>,greater<int> >Q;//小根堆 
priority_queue<int,int> >Q;//大根堆
	Q.empty();
	Q.pop();
	Q.push();
	Q.size();
	Q.top();

set:

//基础操作:	
set<int>se;
unordered_set<int>use;//(不排序) C++11
multiset_set<int>mse;//(不判重)
	se.begin();//返回的是迭代器
	se.clear();
	se.empty();
	se.end();//返回的是迭代器
	se.erase();//erase(iterator) || st.erase(key_value) ||  it=st.find(30); st.erase(it,st.end());
	se.find();//返回的是迭代器 
	se.insert();//insert(key_value); || inset(first,second);
	se.upper_bound();//返回最后一个大于等于key_value的迭代器 
	se.lower_bound();//返回第一个大于等于key_value的迭代器
	se.swap();//交换两个集合 
	se.size();//返回的是数值 
	se.max_size();//返回的是数值 
	se.count();//出现次数(可以判有无,可以是map)

map:

//基础操作
map<int,int>mvp;
map<char,int>mvp;
map<string,int>mvp;
	mvp.clear();

list:

//基础操作
list<int>lis;
	lis.clear();
	lis.empty();
	lis.size();
	lis.front();
	lis.back();
	lis.begin();
	lis.end();
	lis.insert();
	lis.push_back();
	lis.push_front();
	lis.pop_back();
	lis.pop_front();
	lis.merge();//合并两个链表并使之默认升序(也可改), 
	lis.sort();
	lis.unique();
	lis.swap();
	lis.reverse();//逆置 
	lis.assign();
	lis.remove();//lis.remove(x);删去数值为x的数 

vector:

//基础操作
vector<int>V;
	V.clear();
	V.empty();
	V.size();
	V.begin();
	V.end();
	V.push_back();
	V.pop_back();
	V.max_size();
	V.insert();
	V.swap(); 

deque:

deque<int>dQ;
dQ.front();
dQ.back();
dQ.begin();
dQ.end();
dQ.clear();
dQ.empty();
dQ.pop_front();
dQ.pop_back();
dQ.swap();
dQ.push_front();
dQ.push_back();
dQ.insert();
dQ.max_size();
高级数据结构:

ST表:

//O(nlogn)预处理+O(1)查询
//仅能支持RMQ
void STycl()
{
	int k=log(n)/log(2)+1; over(i,1,n) ST[i][0]=a[i];
	over(j,1,t-1) over(i,1,n-(1<<j)+1)
	ST[i][j]=max(S[i][j],ST[i+1<<(j-1)][j-1];
}
void ask(int x,int y)
{
	int k=log(y-x+1)/log(2);
	return max(ST[x][k],ST[y-(1<<k)+1][k]);
}

线段树:

//O(logn)修改,O(logn)查询
struct hit{int l,r,w,lazy;}tr[sea*4];
//建树
void build(int k,int l,int r)
{
	tr[k].l=l,tr[k].r=r;
	if(l==r){tr[k].w=read();return ;}
	int mid=(l+r)>>1;
	build(lk,l,mid); build(rk,mid+1,r);
	tr[k].w=tr[lk].w+tr[rk].w;
}
//标记下传
void down(int k)
{
	if(tr[k].lazy) 
	tr[lk].lazy+=tr[k].lazy; tr[rk].lazy+=tr[k].lazy;
	tr[lk].w+=tr[k].lazy*(tr[lk].r-tr[lk].l+1);
	tr[rk].w+=tr[k].lazy*(tr[rk].r-tr[rk].l+1);
	tr[k].lazy=0;
}
//区间修改(注重优先级,乘法和加法的时候,加法优先)
void alter(int k,int x,int y,int z)
{
	int l=tr[k].l,r=tr[k].r;
	if(l>=x&&r<=y) {tr[k].w+=z*(r-l+1),tr[k].lazy+=z;return ;}
	down(k); int mid=(l+r)>>1;
	if(x<=mid) alter(lk,x,y,z);  if(y>mid) alter(rk,x,y,z);
	tr[k].w=tr[lk].w+tr[rk].w;
}
//区间查询
void ask(int k,int x,int y)
{
	int l=tr[k].l,r=tr[k].r;
	if(l>=x&&r<=y) {ans+=tr[k].w;return;}
	if(tr[k].lazy) down(k);
	int mid=(l+r)>>1;
	if(x<=mid) ask(lk,x,y); if(y>mid) ask(rk,x,y);
}

树状数组:

//O(logn)修改,O(logn)查询,
over(i,1,n) alter(i,a[i]);
//单点修改
void alter(int x,int d){while(x<=n) c[x]+=d,x+=lowbit(x);}
//前缀和
int sum(int x){int s=0;while(x) s+=c[x],x-=lowbit(x);return s;}
//区间修改(差分)
alter(a[x],z),alter(y+1,-z);
//区间查询
sum(y)-sum(x-1);
//树状数组求逆序对(离散化)
over(i,1,n) a[i]=b[i]=read();
sort(a+1,a+n+1); int len=unique(b+1,b+n+1)-b-1;
over(i,1,n) alter(a[i],1),ans+=i-sum(a[i]);

分块:

//O(sqrt(n))修改+O(sqrt(n))查询
void build()
{
	block=sqrt(n); num=n/block+(n%block);
	over(i,1,n) belong[i]=(i-1)/block+1;
	over(i,1,num) l[i]=(i-1)*block+1,r[i]=i*block;r[num]=n;
}
void alter(int x,int y,int kk,int dd)
{
	if(belong[x]==belong[y]) 
    {
        over(i,x,y) 
        {
            //块内暴力处理;
        }
        return ;
    }
	over(i,x,r[belong[x]]) //块外左边暴力
	over(i,belong[x]+1,belong[y]-1) //整块处理(通常数组,函数,vector)
	over(i,l[belong[y]],y) //块外右边暴力
	return ;
}
//查询类似

字符串:

kmp:(对于一个文章串找有多少个单词串)

	int j=0;
	over(i,2,lenb)
	{
		while(j&b[j]!=b[i]) j++;
		if(b[j+1]==b[i]) j++: kmp[i]=j;
	}
	j=0;
	ove(i,1,lena)
	{
		while(j&b[j+1]!=a[i]) j=kmp[j];
		if(b[j+1]==a[i]) j++; 
		if(j==lenb) ans++,j=kmp[j];
	}

manacher:( 求最长回文串的长度 )

void manacher()
{
	int mid=0,mr=0;
	over(i,1,len)
	{
		if(i<mr) hh[i]=min(hh[(mid<<1)-i],mr-i);
		else hh[i]=1;
		while(s[hh[i]+i]==s[i-hh[i]]) hh[i]++;
		if(i+hh[i]>mr) mr=i+hh[i],mid=i;
		ans=max(ans,hh[i]);
	}
}

如果你是风,就不会停。——河马

Continue and never stop……

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值