zoukankan      html  css  js  c++  java
  • 蒟蒻的模板

    快要爆零了敲些模板复习复习,随缘更新

    P3379 【模板】最近公共祖先(LCA)注意t的取值

    #include<bits/stdc++.h>
    using namespace std;
    const int size=500010;
    int n,m,t,f[size][25],root;
    int head[size],ver[2*size],Next[2*size],d[size],tot;
    queue<int>q;
    void add(int x,int y){
    	ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
    }
    void bfs(){
    	q.push(root);d[root]=1;
    	while(q.size()){
    		int x=q.front();q.pop();
    		for(int i=head[x];i;i=Next[i]){
    			int y=ver[i];
    			if(d[y]) continue;
    			d[y]=d[x]+1;
    			f[y][0]=x;
    			for(int j=1;j<=t;++j){
    				f[y][j]=f[f[y][j-1]][j-1];
    			}
    			q.push(y);
    		}
    	}
    }
    int lca(int x,int y){
    	if(d[x]>d[y]) swap(x,y);
    	for(int i=t;i>=0;i--){
    		if(d[f[y][i]]>=d[x]){
    			y=f[y][i];
    		} 
    	}
    	if(x==y) return x;
    	for(int i=t;i>=0;i--){
    		if(f[y][i]!=f[x][i]){
    			y=f[y][i];
    			x=f[x][i];
    		}
    	}
    	return f[x][0];
    }
    int main(){
    	scanf("%d %d %d",&n,&m,&root);
    	t=((int)(log(n)/(log(2))))+1;
    	for(int i=1;i<n;++i){
    		int x,y;
    		scanf("%d %d",&x,&y);
    		add(x,y);add(y,x);
    	}
    	bfs();
    	for(int i=1;i<=m;++i){
    		int x,y;
    		scanf("%d %d",&x,&y);
    		printf("%d
    ",lca(x,y));
    	}
    	return 0;
    }
    

    P3378 【模板】堆(注意更新当前坐标

    #include<bits/stdc++.h>
    using namespace std;
    const int size=1000010;
    int a[size],n,k,x,add;
    void shiftdown(int x){
    	int t;bool flag=1;
    	while(2*x<=add&&flag){
    		if(a[x*2]<a[x]) t=x*2;
    		else t=x;
    		if(2*x+1<=add&&a[x*2+1]<a[t]) t=2*x+1;
    		if(t!=x){
    			swap(a[t],a[x]);
    			x=t;
    		} else flag=0;
    	}
    }
    void updown(int x){
    	bool flag=1;
    	if(x==1) return;
    	while(x!=1&&flag){
    		if(a[x/2]>a[x]) swap(a[x/2],a[x]);
    		else flag=0;
    		x/=2;
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&k);
    		if(k==1){
    			scanf("%d",&x);
    			a[++add]=x;
    			updown(add);
    		}
    		else if(k==2) printf("%d
    ",a[1]);
    		else{
    			a[1]=a[add--];
    			shiftdown(1);
    		}
    	}
    	return 0;
    }
    

    P4549 【模板】裴蜀定理( $ gcd $ 很重要

    #include<bits/stdc++.h>
    using namespace std;
    int n,x,ans;
    int gcd(int a,int b){
    	return b?gcd(b,a%b):a;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&x);
    		x=x<0?-x:x;
    		ans=gcd(x,ans);
    	}printf("%d",ans);
    	return 0;
    }
    

    P3390 【模板】矩阵快速幂(不开 $ longlong $ 见祖宗 $ n,k $ 都要开。

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    long long n,k;
    struct node{
    	long long s[110][110];
    }a,ans;
    node mul(node a,node b){
    	node c;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			c.s[i][j]=0;
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			for(int k=1;k<=n;++k){
    				c.s[i][j]=(c.s[i][j]+(a.s[i][k]*b.s[k][j])%mod)%mod;
    			}
    		}
    	}
    	return c;
    }
    int main(){
    	scanf("%lld %lld",&n,&k);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			scanf("%lld",&a.s[i][j]);
    			ans.s[i][i]=1;
    		}
    	}
    	while(k){
    		if(k&1) ans=mul(ans,a);
    		a=mul(a,a);
    		k>>=1;
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			printf("%lld ",ans.s[i][j]%mod);
    		}printf("
    ");
    	}
    	return 0;
    }
    

    P3385 【模板】负环

    注意初始化,输出,还有spfa出了队列标记要变

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2010;
    const int M=6010;
    int tot,deg[N],head[N],ver[M],edge[M],Next[M];
    int v[N],dis[N];
    queue<int>q;
    int T,n,m;
    void add(int x,int y,int z){
    	ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
    }
    bool spfa(){
    	memset(v,0,sizeof(v));
    	memset(deg,0,sizeof(deg));
    	memset(dis,0x3f,sizeof(dis));
    	dis[1]=0;v[1]=1;q.push(1);
    	while(q.size()){
    		int x=q.front();q.pop();v[x]=0;
    		if(deg[x]==n-1) return false;deg[x]++;
    		for(int i=head[x];i;i=Next[i]){
    			int y=ver[i];
    			if(dis[y]>dis[x]+edge[i]){
    				dis[y]=dis[x]+edge[i];
    				if(!v[y]){v[y]=1,q.push(y);}
    			}
    		}
    	}return true;
    }
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d %d",&n,&m);
    		memset(head,0,sizeof(head));tot=0;
    		for(int i=1;i<=m;++i){
    			int x,y,z;
    			scanf("%d %d %d",&x,&y,&z);
    			z>=0?add(x,y,z),add(y,x,z):add(x,y,z);
    		}
    		spfa()?printf("N0
    "):printf("YE5
    ");
    	}
    	return 0;
    }
    

    P3372 【模板】线段树 1

    蒟蒻线段树区间修改区间查询还敲不出,我太菜了,考前在敲一遍

    #include<bits/stdc++.h>
    using namespace std;
    const int size=100010;
    struct node{
    	long long l,r,data,add;
    }t[4*size];
    long long a[size];
    int n,m,num,x,y;
    long long k;
    void build(long long p,long long l,long long r){
    	t[p].l=l,t[p].r=r;
    	if(l==r){t[p].data=a[l];return;}
    	long long mid=(l+r)>>1;
    	build(p*2,l,mid);
    	build(p*2+1,mid+1,r);
    	t[p].data=t[p*2].data+t[p*2+1].data;
    }
    void lazy(long long p){
    	if(t[p].add){
    		t[p*2].data+=t[p].add*(t[p*2].r-t[p*2].l+1);
    		t[p*2+1].data+=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);
    		t[p*2].add+=t[p].add;
    		t[p*2+1].add+=t[p].add;
    		t[p].add=0;
    	}
    } 
    void change(long long p,long long l,long long r,long long v){
    	if(l<=t[p].l&&r>=t[p].r){t[p].data+=v*(t[p].r-t[p].l+1);t[p].add+=v;return;}
    	lazy(p);
    	int mid=(t[p].l+t[p].r)>>1;
    	if(l<=mid) change(p*2,l,r,v);
    	if(r>mid) change(p*2+1,l,r,v);
    	t[p].data=t[p*2].data+t[p*2+1].data;
    }
    long long ask(long long p,long long l,long long r){
    	if(l<=t[p].l&&r>=t[p].r) return t[p].data;
    	lazy(p);
    	long long mid=(t[p].l+t[p].r)>>1;
    	long long val=0;
    	if(l<=mid) val+=ask(p*2,l,r);
    	if(r>mid) val+=ask(p*2+1,l,r);
    	return val;
    }
    int main(){
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
    	build(1,1,n);
    	for(int i=1;i<=m;++i){
    		scanf("%d",&num);
    		if(num==1){
    			scanf("%d %d %lld",&x,&y,&k);
    			change(1,x,y,k);
    		}else{
    			scanf("%d %d",&x,&y);
    			printf("%lld
    ",ask(1,x,y));
    		}
    	}
    	return 0;
    }
    

    P4777 【模板】扩展中国剩余定理(EXCRT)

    这个以前敲的,先挂着,有时间来敲

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=300010;
    long long a[maxn],b[maxn],ans;
    int n;
    long long clu(long long a,long long b,long long p){
    	long long tmp=0;
    	while(b>0){
    		if(b&1) tmp=(tmp+a)%p;
    		a=(a+a)%p;
    		b>>=1;
    	}
    	return tmp;
    }
    long long exgcd(long long a,long long b,long long &x,long long &y){
    	if(b==0){
    		x=1,y=0;
    		return a;
    	}  
    	long long gcd=exgcd(b,a%b,x,y);
    	long long tmp=x;
    	x=y,y=tmp-a/b*y;
    	return gcd;
    }
    long long solve(){
    	long long x,y,k;
    	long long M=a[1];
    	ans=b[1];
    	for(int i=2;i<=n;++i){
    		long long ai=M,bi=a[i],c=(b[i]-ans%bi+bi)%bi;
    		long long gcd=exgcd(ai,bi,x,y),tmp=bi/gcd;
    		if(c%gcd!=0) return -1;
    		x=clu(x,c/gcd,tmp);
    		ans+=x*M;
    		M*=tmp;
    		ans=(ans%M+M)%M;
    	}
    	return (ans%M+M)%M;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%lld %lld",&a[i],&b[i]);
    	}
    	printf("%lld",solve());
    	return 0;
    }
    

    P3382 【模板】三分法

    秦九昭公式求多项式一开始打反了。。。什么 $ lj $ 样例,次数大的先扫,注意从0开始,其余三分模板

    #include<bits/stdc++.h>
    using namespace std;
    const double esp=1e-9;
    int n;
    double l,r,ans,xi[20];
    double clu(double x){
    	double ans=0;
    	for(int i=0;i<=n;++i){
    		ans=ans*x+xi[i];
    	}
    	return ans;
    }
    int main(){
    	scanf("%d %lf %lf",&n,&l,&r);
    	for(int i=0;i<=n;++i){
    		scanf("%lf",&xi[i]);
    	}
    	while(l+esp<=r){
    		double lm=l+(r-l)/3.0;
    		double rm=r-(r-l)/3.0;
    		if(clu(lm)<clu(rm)) l=lm;
    		else r=rm;
    	}printf("%.5lf",l);
    	return 0;
    }
    

    P2197 【模板】nim游戏

    水题不多说,可以参照hdu 1850

    #include<bits/stdc++.h>
    using namespace std;
    int T,n;
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		int ans=0,k;
    		for(int i=1;i<=n;++i) scanf("%d",&k),ans^=k;
    		ans?printf("Yes
    "):printf("No
    "); 
    	}
    	return 0;
    }
    
    

    P4779 【模板】单源最短路径(标准版)

    $ dijkstra $ 无法处理负环,并且写法上同spfa有差异。

    注意stl

    priority_queue< node> q
     
    bool poerator <(const node &x)const{return x.dis<dis;}
    

    注意注意!!$ spfa $ 中 $ v $ 表示是否在队列里,而 $ dijkstra $表示是否拓展

    #include<bits/stdc++.h>
    using namespace std;
    const int size=100010;
    int n,m,s;
    int head[size],ver[2*size],Next[2*size],edge[2*size],tot;
    int dis[size],v[size];
    struct node{
    	int dis;
    	int num;
    	bool operator <(const node &x) const{
    		return x.dis<dis;
    	} 
    };
    priority_queue<node>q;
    void add(int x,int y,int z){
    	ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
    }
    void dija(){
    	memset(dis,0x3f,sizeof(dis));
    	memset(v,0,sizeof(v));
    	dis[s]=0;q.push((node){0,s});
    	while(q.size()){
    		int x=q.top().num;q.pop();
    		if(v[x]) continue;v[x]=1;//只能扩展一次
    		for(int i=head[x];i;i=Next[i]){
    			int y=ver[i];
    			if(dis[y]>dis[x]+edge[i]){
    				dis[y]=dis[x]+edge[i];
    				if(!v[y]){q.push((node){dis[y],y});}//这里不需要标记
    			}
    		}
    	}
    }
    int main(){
    	scanf("%d %d %d",&n,&m,&s);
    	for(int i=1;i<=m;++i){
    		int x,y,z;
    		scanf("%d %d %d",&x,&y,&z);
    		add(x,y,z);
    	}
    	dija();
    	for(int i=1;i<=n;++i){
    		printf("%d ",dis[i]);
    	}
    	return 0;
    }
    

    P3386 【模板】二分图匹配(匈牙利算法

    连单向边,并且判断边的存在才能去匹配

    #include<bits/stdc++.h>
    using namespace std;
    const int size=1010;
    int n,m,e;
    int a[size][size],v[size],match[size];
    bool dfs(int x){
    	for(int i=1;i<=m;++i){
    		if(a[x][i]){
    			if(v[i]) continue;
    			v[i]=1;
    			if(match[i]==-1||dfs(match[i])){
    				match[i]=x;
    				return 1;
    			}
    		}
    	}return 0;
    }
    int solve(){
    	int ans=0;
    	memset(match,-1,sizeof(match));
    	for(int i=1;i<=n;++i){
    		memset(v,0,sizeof(v));
    		if(dfs(i)) ans++;
    	}
    	return ans;
    }
    int main(){
    	scanf("%d %d %d",&n,&m,&e);
    	for(int i=1;i<=e;++i){
    		int x,y;
    		scanf("%d %d",&x,&y);
    		if(x>=1&&x<=n&&y>=1&&y<=m) a[x][y]=1;
    	}
    	printf("%d",solve());
    	return 0;
    }
    

    P3366 【模板】最小生成树 $ Kruskal $

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5010;
    const int M=400010;
    struct node{
    	int u,v,dis;
    }edge[M];
    int n,m,tot=1;
    int fa[N];
    long long ans;
    bool cmp(node a,node b){
    	return a.dis<b.dis;
    }
    int find(int x){
    	return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    int main(){
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=m;++i){
    		int x,y,z;
    		scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].dis);
    	}
    	for(int i=1;i<=n;++i) fa[i]=i;
    	sort(edge+1,edge+1+m,cmp);
    	for(int i=1;i<n;++i){
    		while(find(edge[tot].u)==find(edge[tot].v)) tot++;
    		fa[find(edge[tot].u)]=find(edge[tot].v);ans+=edge[tot].dis;
    	}printf("%lld",ans);
    	return 0;
    }
    

    P3366 【模板】最小生成树 $ Prim $

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5010;
    const int M=400010;
    int n,m;
    long long ans;
    int tot,head[N],ver[M],Next[M],edge[M];
    int v[N],dis[N];
    void add(int x,int y,int z){
    	ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
    }
    int main(){
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=m;++i){
    		int x,y,z;
    		scanf("%d %d %d",&x,&y,&z);
    		add(x,y,z);add(y,x,z);
    	}
    	memset(dis,0x3f,sizeof(dis));
    	memset(v,0,sizeof(v));
    	v[1]=1;dis[1]=0;
    	for(int i=head[1];i;i=Next[i]){
    		int y=ver[i],z=edge[i];
    		dis[y]=min(dis[y],z);
    	}
    	for(int t=1;t<n;++t){
    		int minn=1<<30;
    		int op=1;
    		for(int i=1;i<=n;++i){
    			if(!v[i]&&dis[i]<minn){
    				minn=dis[i];
    				op=i;
    			}
    		}
    		if(v[op]) continue;
    		v[op]=1;ans+=minn;
    		for(int i=head[op];i;i=Next[i]){
    			int y=ver[i];
    			if(!v[y]&&dis[y]>edge[i]){
    				dis[y]=edge[i];
    			}
    		}
    	}
    	ans>1<<30?printf("orz"):printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    BroadcastReceiver之发送自定义无序广播
    BroadcastReceiver之应用卸载和安装监听
    Android几种打开SQLite的方法
    BroadcoastReceiver之短信到来监听和获取内容
    BroadcastReceiver之SD的挂载监听
    BroadcastReceive之ip拨号
    Activity之多启动图标
    Uwp Windows10获取设备位置(经纬度)
    DeviceFamily XAML Views(一)
    [SCOI2010]生成字符串
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11819120.html
Copyright © 2011-2022 走看看