模板大集合

模板大集合

适合理解,学习

最新的更改将会在以下几个链接中

汇总

DP

图论

数学

数据结构

其他

思维导图

生命不息,更新不止!

DP

最长下降子序列

#include<bits/stdc++.h>
using namespace std;
int n,maxn,a[110000],f[110000];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),f[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<i;j++)
			if(a[i]<a[j])//*1
				f[i]=max(f[i],f[j]+1);
	for(int i=1;i<=n;i++)maxn=max(maxn,f[i]);
	printf("%d",maxn);
}
//*1
//最长不下降子序列:a[i]>=a[j]
//最长上升子序列:a[i]>a[j]
//最长不上升子序列:a[i]<=a[j]
//最长下降子序列:a[i]<a[j]

优化

#include<bits/stdc++.h>
using namespace std;
int n,tot=1,a[110000],f[110000];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	f[1]=a[1];
	for(int i=2;i<=n;i++){
		if(a[i]>f[tot])f[++tot]=a[i];
		else f[lower_bound(f+1,f+tot+1,a[i])-f]=a[i];//*1
	}
	printf("%d",tot);
}
//最长上升子序列f[lower_bound(f+1,f+tot+1,a[i])-f]=a[i];
//最长不下降子序列f[upper_bound(f+1,f+tot+1,a[i])-f]=a[i];

背包

图论

最短路

Floyd

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,x,y,z,dis[1100][1100];
void floyd(){
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(dis[i][j]>dis[i][k]+dis[k][j])
					dis[i][j]=dis[i][k]+dis[k][j];
}
int main(){
	scanf("%lld%lld",&n,&m);
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld",&x,&y,&z);
		dis[x][y]=dis[y][x]=z;
	}
	floyd();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)printf("%lld ",dis[i][j]);
		puts("");
	}
}

dijikstra

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,s,x,y,z,ans,tot=1,head[110000],dis[110000],vis[110000];
struct node{
	ll to,dis,nxt;
}e[420000];
void add(ll f,ll to,ll dis){
	e[++tot].to=to;
	e[tot].dis=dis;
	e[tot].nxt=head[f];
	head[f]=tot;
}
struct nd{
	ll i,dis;
	bool operator < (const nd &tmp)const{
		return dis>tmp.dis;
	}
};
priority_queue<nd>q;
void dijikstra(){
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	q.push((nd){s,0});
	while(!q.empty()){
		ll u=q.top().i;
		q.pop();
		if(vis[u])continue;
		vis[u]=1;
		for(ll i=head[u];i;i=e[i].nxt){
			ll v=e[i].to;
			if(!vis[v]&&dis[v]>dis[u]+e[i].dis){
				dis[v]=dis[u]+e[i].dis;
				q.push((nd){v,dis[v]});
			}
		}
	}
}
int main(){
	scanf("%lld%lld%lld",&n,&m,&s);
	for(ll i=1;i<=m;i++){
		scanf("%lld%lld%lld",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	dijikstra();
	for(ll i=1;i<=n;i++)if(dis[i]!=0x3f3f3f3f)
		printf("from%lldto%lld:%lld\n",s,i,dis[i]);
}

bellman-ford

bellman-ford.jpg

SPFA

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,s,x,y,z,ans,tot=1,head[110000],dis[110000],vis[110000];
struct node{
	ll to,dis,nxt;
}e[420000];
void add(ll f,ll to,ll dis){
	e[++tot].to=to;
	e[tot].dis=dis;
	e[tot].nxt=head[f];
	head[f]=tot;
}
queue<ll>q;
void SPFA(){
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	vis[s]=1;
	q.push(s);
	while(!q.empty()){
		ll u=q.front();
		q.pop();
		for(ll i=head[u];i;i=e[i].nxt){
			ll v=e[i].to;
			if(dis[v]>dis[u]+e[i].dis){
				dis[v]=dis[u]+e[i].dis;
				if(!vis[v])vis[v]=1,q.push(v);
			}
		}
		vis[u]=0;
	}
}
int main(){
	scanf("%lld%lld%lld",&n,&m,&s);
	for(ll i=1;i<=m;i++){
		scanf("%lld%lld%lld",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	SPFA();
	for(ll i=1;i<=n;i++)if(dis[i]!=0x3f3f3f3f)
		printf("from%lldto%lld:%lld\n",s,i,dis[i]);
}

bfs+拆边

#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,x,y,z,kkk,ans,tot=1,N=5005000,head[11000000],dis[11000000];
bool c[11000000];
struct node{
	int to,dis,nxt;
}e[42000000];
void add(int f,int to){
	e[++tot].to=to;
	e[tot].nxt=head[f];
	head[f]=tot;
}
queue<int>q;
int main(){
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&z);
		if(z==1){
			add(x,y);
			add(y,x);
		}
		if(z==2){
			add(x,++n);
			add(n,y);
			add(n,x);
			add(y,n);
		}
	}
	memset(dis,0x7f,sizeof(dis));
	dis[s]=0;
	q.push(s);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			if(dis[v]>dis[u]+1)dis[v]=dis[u]+1,q.push(v);
			if(v==t){
				printf("%d",dis[v]);
				return 0;
			}
		}
	}
}

注:

1.多源最短路:Floyd(O(N^3))

2.单源最短路:Dijikstra(O(NlogN))、Bellman-ford(O(MN))、SPFA(O(N+M))

3.除Dijikstra外其余都可以处理负权边,都不可以处理负权环。

4.SPFA会被卡

LCA

倍增法

#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,r,cnt,head[500005],f[500005][22],dep[500005];
struct node{
	int to,nxt;
}e[1000005];
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void dfs(int u,int fa){
	dep[u]=dep[fa]+1;
	for(int i=1;(1<<i)<=dep[u];i++){
		f[u][i]=f[f[u][i-1]][i-1];
	}
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa) continue;
		f[v][0]=u;
		dfs(v,u);
	}
}
int lca(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=20;i>=0;i--){
		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
		if(x==y) return x;
	}
	for(int i=20;i>=0;i--){
		if(f[x][i]!=f[y][i]){
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
int main(){
	cin>>n>>m>>r;
	for(int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs(r,0);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&u,&v);
		printf("%d\n",lca(u,v));
	} 
}

Tarjan法

#include<bits/stdc++.h>
using namespace std;
int n,q,s,cnt,cnt2,head[500005],qhead[500005],f[500005],yy;
bool vis[500005];
struct edge{
	int to,nxt;
}e[1000005];
struct qedge{
	int to,nxt,lca;
}qe[1000005];
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void add2(int u,int v){
	qe[++cnt2].to=v;
	qe[cnt2].nxt=qhead[u];
	qhead[u]=cnt2;
}
int getf(int x){
	if(x==f[x]) return x;
	return f[x]=getf(f[x]);
}
void tarjan(int u){
	vis[u]=1;
	f[u]=u;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(vis[v]) continue;
		tarjan(v);
		f[v]=u;
	}
	for(int i=qhead[u];i;i=qe[i].nxt){
		int v=qe[i].to;
		if(vis[v]){
			qe[i].lca=getf(v);
			if(i%2) qe[i+1].lca=qe[i].lca;
			else qe[i-1].lca=qe[i].lca;
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&q,&s);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=q;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add2(u,v);
		add2(v,u);
	}
	tarjan(s);
	for(int i=1;i<=q;i++) printf("%d\n",qe[2*i].lca);
}

Tarjan

求强连通分量

#include<bits/stdc++.h>
using namespace std;
int m,n,x,y,kkk,tot,cnt,dfn[11000],low[11000],s[11000],head[11000];
bool c[11000];
struct node{
	int to,nxt;
}e[55000];
void add(int f,int to){
	e[++kkk].to=to;
	e[kkk].nxt=head[f];
	head[f]=kkk;
}
void tarjan(int u){
	dfn[u]=low[u]=++cnt;
	s[++tot]=u;
	c[u]=1;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(c[v])low[u]=min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		do{
			cout<<s[tot]<<" ";
			c[s[tot]]=0;
			tot--;
		}while(u!=s[tot+1]);
		cout<<endl;
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		add(x,y);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
}

求割点

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,tot,root,head[1005],dfn[1005],low[1005],f[1005];
bool flag[1005];
struct edge{
	int to,nxt;
}e[500005]; 
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void tarjan(int u,int fa){
	dfn[u]=low[u]=++tot;
	int child=0;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			child++;
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
			if(u==root && child>=2) flag[u]=1;
			else if(u!=root && dfn[u]<=low[v]) flag[u]=1;
		}
		else if(v!=fa)
			low[u]=min(low[u],dfn[v]);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	root=1;
	tarjan(root,root);
	for(int i=1;i<=n;i++) if(flag[i]) cout<<i<<" ";
}

求桥

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,tot,root,head[1005],dfn[1005],low[1005],f[1005];
bool flag[1005];
struct edge{
	int to,nxt;
}e[500005]; 
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void tarjan(int u,int fa){
	dfn[u]=low[u]=++tot;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<low[v]) cout<<u<<" -> "<<v<<endl;
		}
		else if(v!=fa)
			low[u]=min(low[u],dfn[v]);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	root=1;
	tarjan(root,root);
}

求双连通分量

#include<bits/stdc++.h>
#define N 110000
using namespace std;
int n,m,q,kkk,tot,cnt,col,head[N],low[N],dfn[N],s[N],color[N];
struct node{
	int to,nxt;
}e[550000];
void add(int f,int to){
	e[++kkk].to=to;
	e[kkk].nxt=head[f];
	head[f]=kkk;
}
void tarjan(int u,int fa){
	bool flag=0;
	low[u]=dfn[u]=++cnt;
	s[++tot]=u;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(v!=fa||flag)low[u]=min(low[u],dfn[v]);
		else flag=1;
	}
	if(low[u]==dfn[u]){
		col++;
		do{
			cout<<s[tot]<<' ';
			color[s[tot]]=col;
			tot--;
		}while(s[tot+1]!=u);
		puts("");
	}
}

数学

gcd&exgcd

#include<bits/stdc++.h>
using namespace std;
int a,b,x,y;
int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int tmp=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return tmp;
}
int gcd(int a,int b){
	if(!b)return a;
	return gcd(b,a%b);
}
int main(){
	scanf("%d%d",&a,&b);
	exgcd(a,b,x,y);
	printf("%d",(x%b+b)%b);
}

快速幂

#include<bits/stdc++.h>
using namespace std;
int a,b,n;
int cal(int a,int b){
	int t=1,base=a;
	while(b){
		if(b&1)t=t*base;
		base*=base;
		b>>=1;
	}
	return t;
}
int main(){
	cin>>a>>b;
	cout<<cal(a,b);
}

矩阵快速幂

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,K,inf=1000000007;
struct node{
	ll u[110][110];
	node(){
		memset(u,0,sizeof(u));
	}
	void o(){
		for(int i=1;i<=n;i++)u[i][i]=1;
	}
}a,ans;
node operator*(const node &a,const node &b){
	node c;
	for(ll k=1;k<=n;k++)for(ll i=1;i<=n;i++)
		for(ll j=1;j<=n;j++)c.u[i][j]=(c.u[i][j]+a.u[i][k]*b.u[k][j]%inf)%inf;
	return c;
}
int main(){
	scanf("%lld%lld",&n,&K);
	for(ll i=1;i<=n;i++)
		for(ll j=1;j<=n;j++)
			scanf("%lld",&a.u[i][j]);
	ans.o();
	while(K){
		if(K&1)ans=ans*a;
		a=a*a;
		K>>=1;
	}
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=n;j++)
			printf("%lld ",ans.u[i][j]);
		puts("");
	}
}

数据结构

#include<bits/stdc++.h>
using namespace std;
int n,cnt,x,y,t[110000];
void push(int x){
	t[++cnt]=x;
	int tmp=cnt;
	while(tmp>1){
		int fa=tmp/2;
		if(t[tmp]>=t[fa])return;
		swap(t[fa],t[tmp]);
		tmp=fa;
	}
}
int top(){
	return t[1];
}
void pop(){
	t[1]=t[cnt--];
	int tmp=1;
	while(tmp*2<=cnt){
		int lc=2*tmp;
		if(lc<cnt&&t[lc]>t[lc+1])lc++;
		if(t[tmp]<=t[lc])break;
		swap(t[tmp],t[lc]);
		tmp=lc;
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&x);
		if(x==1){
			scanf("%d",&y);
			push(y);
		}
		else if(x==2)printf("%d\n",top());
		else pop();
	}
}

树状数组

单改区查

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,z,a[110000],c[1100000];
int lowbit(int i){
	return i&(-i);
}
void updata(int i,int k){
	while(i<=n){
		c[i]+=k;
		i+=lowbit(i);
	}
}
int getsum(int i){
	int sum=0;
	while(i>0){
		sum+=c[i];
		i-=lowbit(i);
	}
	return sum;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),updata(i,a[i]);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&z);
		if(x==1)updata(y,z);
		else printf("%d\n",getsum(z)-getsum(y-1));
	}
}

区改单查

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,z,a[1100000],c[1100000];
int lowbit(int i){
	return i&(-i);
}
void updata(int i,int k){
	while(i<=n){
		c[i]+=k;
		i+=lowbit(i);
	}
}
int getsum(int i){
	int sum=0;
	while(i>0){
		sum+=c[i];
		i-=lowbit(i);
	}
	return sum;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),updata(i,a[i]-a[i-1]);
	for(int i=1;i<=m;i++){
		scanf("%d",&x);
		if(x==1){
			scanf("%d%d%d",&x,&y,&z);
			updata(x,z);
			updata(y+1,-z);
		}
		else{
			scanf("%d",&x);
			printf("%d\n",getsum(x));
		}
	}
}

区改区查

#include<bits/stdc++.h>
int n,m,x,y,z,a[110000],c[110000],d[110000];
using namespace std;
int lowbit(int i){
	return i&(-i);
}
void updata(int i,int k){
	int x=i-1;
	while(i<=n){
		c[i]+=k;
		d[i]+=k*x;
		i+=lowbit(i);
	}
}
int getsum(int i){
	int sum=0,x=i;
	while(i>0){
		sum+=x*c[i]-d[i];
		i-=lowbit(i);
	}
	return sum;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),updata(i,a[i]);
	for(int i=1;i<=m;i++){
		scanf("%d",&x);
		if(x==1){
			scanf("%d%d%d",&x,&y,&z);
			updata(x,z);
			updata(y+1,-z);
		}
		else{
			scanf("%d%d",&x,&y);
			printf("%d\n",getsum(y)-getsum(x-1));
		}
	}
}

字符串

马拉车(manacher)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define writeln(a) write(a),puts("")
#define writesp(a) write(a),putchar(" ")
#define repn(i,a,b,c) for(int i=a;i<=b;i+=(c))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i--)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
inline int read(){
	char ch=getchar();int f=0,sum=0;
	while(!isdigit(ch))ch|=(f=='-'),ch=getchar();
	while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
	return f?-sum:sum;
}
void write(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
#define N 11000000
char s[20*N],t[40*N];
int ans,n,m,r,mid,l[N],k[2*N];
int main(){
	scanf("%s",s+1);
	int n=strlen(s+1);m=n*2+1;
	rep(i,1,n)t[i*2]=s[i];
	rep(i,0,n)t[i*2+1]='#';
	t[0]='@',t[m+1]='&';r=0,mid=0;
	rep(i,1,m){
		if(i<=r)k[i]=min(r-i,k[mid*2-i]);
		else k[i]=1;
		while(i+k[i]<=m&&i-k[i]>=1&&t[i+k[i]]==t[i-k[i]])k[i]++;
		if(i+k[i]>r)r=i+k[i],mid=i;
		ans=max(ans,k[i]);
	}
	printf("%d",ans-1);
//	repn(i,1,m,2)l[i/2]=(k[i]-1)/2,cout<<l[i/2]<<' ';
}

其他

排序

快速排序

#include<bits/stdc++.h>
using namespace std;
int n,a[100];
void qsort(int l,int r){
	int i=l,j=r,mid=a[(l+r)/2];
	while(i<=j){
		while(a[i]<mid)i++;
		while(a[i]<mid)j--;
		if(i<=j){
			swap(a[i],a[j]);
			i++;
			j--;
		}
	}
	if(i<r)qsort(i,r);
	if(j>l)qsort(l,j);
}
int main(){
	cin>>n;
	srand(time(0));
	for(int i=1;i<=n;i++)a[i]=rand()%1000,cout<<a[i]<<" ";
	cout<<endl;
	qsort(1,n);
	for(int i=1;i<=n;i++)cout<<a[i]<<" ";
}

基数排序(不是WindowsXP提供的)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,a[maxn],b[maxn],cnt[10],mx;
void solve(){
    int pos=1;
    while(pos<=mx){
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++)++cnt[a[i]/pos%10];
        for(int i=1;i<10;i++)cnt[i]+=cnt[i-1];
        for(int i=n;i>=1;i--)b[cnt[a[i]/pos%10]--]=a[i];
        for(int i=1;i<=n;i++)a[i]=b[i];
        pos*=10; 
    }
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),mx=max(mx,a[i]);
    solve();
}

归并排序

#include<bits/stdc++.h>
using namespace std;
int n,a[1000],b[1000];
void meger(int l,int r){
    int i=l,mid=(l+r)/2,j=mid+1,k=l;
    while(i<=mid && j<=r){
        if(a[i]<a[j])b[k++]=a[i++];
        else b[k++]=a[j++];
    }
    while(i<=mid) b[k++]=a[i++];
    while(j<=r) b[k++]=a[j++];
    for(int i=l;i<=r;i++)a[i]=b[i];
}

void megersort(int l,int r){
    if(l==r) return;
    int mid=(l+r)/2;
    megersort(l,mid);
    megersort(mid+1,r);
    meger(l,r);
}

int main(){
    cin>>n;
    srand(time(0));
    for(int i=1;i<=n;i++)a[i]=rand() % 1000,cout<<a[i]<<" ";
    cout<<endl;
    megersort(1,n);
    for(int i=1;i<=n;i++)cout<<a[i]<<" "; 
}

堆排序

#include<bits/stdc++.h>
using namespace std;
int n,a[11000];
void heap(int i,int m){
	int j=i*2;
	while(j<=m){
		if(j<m&&a[j]<a[j+1])j++;
		if(a[i]>a[j])break;
		swap(a[i],a[j]);
		i=j,j=i*2;
	}
}
void heapsort(){
	for(int i=n/2;i>0;i--)heap(i,n);
	for(int i=n;i>=2;i--){
		cout<<a[1]<<' ';
		a[1]=a[i];
		heap(1,i-1);
	}
	cout<<a[1];
}
int main(){
	cin>>n;
	srand(time(0));
	for(int i=1;i<=n;i++)a[i]=rand()%1000,cout<<a[i]<<" ";
	cout<<endl;
	heapsort();
}

其他排序

ST算法(RMQ问题)

#include<bits/stdc++.h>
using namespace std;
int n,m,l,r,a[110000],f[110000][25];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),f[i][0]=a[i];
	for(int j=1;(1<<j)-1<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)
		f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&l,&r);
		int k=log2(r-l+1);
		printf("%d\n",max(f[l][k],f[r-(1<<k)+1][k]));
	}
}

线性筛

#include<bits/stdc++.h>
using namespace std;
int n,cnt,s[11000000];
bool su[110000000];
int main(){
	scanf("%d",&n);
	for(int i=2;i<=n;i++){
		if(!su[i])s[++cnt]=i;
		for(int j=1;j<=cnt&&i*s[j]<=n;j++){
			su[i*s[j]]=1;
			if(i%s[j]==0)break;
		}
	}
	for(int i=1;i<=cnt;i++)printf("%d,",s[i]);
	cout<<cnt;
}

高精度(已封装代码,玩玩就行)

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 1005;
struct bign
{
    int len,s[N];
    bign()  {  memset(s,0,sizeof(s));  len=1;  }
    bign(int num)  {  *this=num; }
    bign(char *num) { *this=num; }
    bign operator =(int num)
    {
        char c[N];
        sprintf(c,"%d",num);
        *this=c;
        return *this;
    }
    bign operator =(const char *num)
    {
        len=strlen(num);
        for (int i=0;i<len;i++) s[i]=num[len-1-i]-'0';
        return *this;
    }
    string str()
    {
        string res="";
        for (int i=0;i<len;i++) res=(char)(s[i]+'0')+res;
        return res;
    }
    void clean()
    {
        while (len>1&&!s[len-1]) len--;
    }
    bign operator +(const bign &b)
    {
        bign c;    
        c.len=0;
        for (int i=0,g=0;g||i<len||i<b.len;i++)
        {
            int x=g;
            if (i<len) x+=s[i];
            if (i<b.len) x+=b.s[i];
            c.s[c.len++]=x%10;
            g=x/10;
        }
        return c;
    }
    bign operator -(const bign &b)
    {
        bign c;
        c.len=0;
        int x;     
        for (int i=0,g=0;i<len;i++)
        {
            x=s[i]-g;
            if (i<b.len) x-=b.s[i];
            if (x>=0) g=0;
            else{          
                x+=10;
                g=1;
            };
            c.s[c.len++]=x;
        }
        c.clean();
        return c;
    }
    bign operator *(const bign &b)
    {
        bign c;
        c.len=len+b.len;
        for (int i=0;i<len;i++) for (int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j];
        for (int i=0;i<c.len-1;i++) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; }
        c.clean();
        return c;  
    }
    bool operator <(const bign &b)
    {
        if (len!=b.len) return len<b.len;
        for (int i=len-1;i>=0;i--)
             if (s[i]!=b.s[i]) return s[i]<b.s[i];
        return false;
    }
    bign operator +=(const bign &b)
    {
        *this=*this+b;
        return *this;
    }
    bign operator -=(const bign &b)
    {
        *this=*this-b;
        return *this;
    }  
};
istream& operator >>(istream &in,bign &x)
{
  string s;
  in>>s;
  x=s.c_str();
  return in;
}
ostream& operator <<(ostream &out,bign &x)
{
    out<<x.str();
    return out;
}
int main(){
    bign a,b,c;
    ios::sync_with_stdio(false);
    cin>>a>>b;
    c=a+b;
    cout<<c<<endl;
    return 0;
}

快读快写

inline int read(){
		int sum=0,f=0;char c=getchar();
		while(!isdigit(c))f|=(c=='-'),c=getchar();
		while(isdigit(c))sum=(sum<<1)+(sum<<3)+(c^48),c=getchar();
		return f?-sum:sum;
	}
	void write(int k){
		if(k<0)putchar('-'),k=-k;
		write(k/10);
		putchar(k%10+48);
	}

快读getchar优化(仅限文操)

#define getchar nc
char nc(){
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}

众数

#include<bits/stdc++.h>
using namespace std;
int n,l,cnt,m;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&m);
		if(l==m)cnt++;
		if(!cnt)l=m,cnt=1;
		if(l!=m)cnt--;
	}
	printf("%d",l);
}

离散化

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[100],b[100],n,m;
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
    sort(a+1,a+n+1);
    int size=unique(a+1,a+n+1)-a-1;
    for (int i=1;i<=n;i++) b[i]=lower_bound(a+1,a+size+1,b[i])-a;
    for (int i=1;i<=n;i++) cout<<b[i];
}

逆元

就是\(x^{mod-2}\)


动态众数

#define N 110000
#define inf 1145141919810
ll n;
struct CQ{
	priority_queue<ll>bq;priority_queue<ll,vector<ll>,greater<ll> >sq;
	void add(ll k){
		if(k>bq.top())sq.push(k);
		else bq.push(k);
		if(bq.size()>sq.size()+1)sq.push(bq.top()),bq.pop();
		if(bq.size()<sq.size())bq.push(sq.top()),sq.pop();
	}
	ll qur(){return bq.top();}
	void init(){while(!sq.empty())sq.pop();while(!bq.empty())bq.pop();bq.push(-inf);sq.push(inf);}
}Q;
int main(){
	Q.init();
	n=read();rep(i,1,n)Q.add(read());
	writeln(Q.qur());
}

剪切板:

#include<bits/stdc++.h>
using namespace std;
#define writeln(a) write(a),puts("")
#define writesp(a) write(a),putchar(" ")
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i--)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
inline int read(){
	char ch=getchar();int f=0,sum=0;
	while(!isdigit(ch))ch|=(f=='-'),ch=getchar();
	while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
	return f?-sum:sum;
}
void write(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
#define N 110000
int n,d,mod=999,mul[N],inv[N];
int mi(int a,int k){
	int sum=1;
	while(k){
		if(k&1)sum=sum*a%mod;
		a=a*a%mod;
		k>>=1;
	}
	return sum;
}
void init(int n){
	mul[0]=inv[0]=1;
	rep(i,1,n)mul[i]=mul[i-1]*i%mod;
	inv[n]=mi(mul[n],mod-2);
	drep(i,n-1,1)inv[i]=inv[i+1]*(i+1)%mod;
}
int C(int n,int m){
	if(n<0||m<0||n<m)return 0;
	return mul[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
	init(100);
	cout<<C(5,3);
}
posted @ 2020-06-06 21:35  ZTC_ZTC  阅读(310)  评论(0编辑  收藏  举报