常用板子
1.并查集
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define maxn 5003
using namespace std;
int fa[maxn],n,m,p,a,b;
int find(int x)
{
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}
void hb(int x,int y)
{
fa[x]=y;
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=0;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
cin>>a>>b;
int r1=find(a);
int r2=find(b);
if(r1!=r2) hb(r1,r2);
}
for(int i=1;i<=p;i++)
{
cin>>a>>b;
int r1=find(a);
int r2=find(b);
if(r1==r2) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
2.SPFA(单源最短路)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define INF 0x7fffffff
#define maxn 10000+4
#define maxm 500000+5
using namespace std;
struct edge{
int to,dis,nxt;
}e[maxm];
int num=0,h[maxn];
void add(int from,int to,int dis)
{
e[++num].nxt=h[from];
e[num].dis=dis;
e[num].to=to;
h[from]=num;
return ;
}
int q[maxm],l[maxn],head=0,tail=0,n,m,s;
bool vis[maxn];
void spfa()
{
vis[s]=1;q[++tail]=s;l[s]=0;
while(head<tail){
int j=q[++head];
vis[j]=0;
int p=h[j];
while(p){
int to=e[p].to;
if(l[to]>l[j]+e[p].dis){
l[to]=l[j]+e[p].dis;
if(vis[to]==0){
vis[to]=1;
q[++tail]=to;
}
}
p=e[p].nxt;
}
}
return ;
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=n;i++) l[i]=INF;
memset(vis,0,sizeof(vis));
memset(h,0,sizeof(h));
for(int i=1,u,v,w;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
spfa();
for(int i=1;i<=n;i++)
{
printf("%d ",l[i]);
}
return 0;
}
3.线段树
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define maxn 100005
#define LL long long
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
using namespace std;
LL sum[maxn<<2],add[maxn<<2];
void putdown(int rt,int len)
{
LL y=add[rt];
if(y){
add[rt<<1]+=y;
add[rt<<1|1]+=y;
sum[rt<<1]+=(y*(len-(len>>1)));
sum[rt<<1|1]+=(y*(len>>1));
add[rt]=0;
}
return ;
}
void getup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
return ;
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R){
add[rt]+=c;
sum[rt]+=(c*(r-l+1));
return ;
}
int mid=(l+r)>>1;
putdown(rt,r-l+1);
if(L<=mid) update(L,R,c,ls);
if(mid<R) update(L,R,c,rs);
getup(rt);
return ;
}
LL query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
return sum[rt];
}
int mid=(l+r)>>1;
LL t=0;
putdown(rt,r-l+1);
if(L<=mid) t+=query(L,R,ls);
if(mid<R) t+=query(L,R,rs);
return t;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1,k;i<=n;i++)
{
scanf("%d",&k);
update(i,i,k,1,n,1);
}
for(int i=1,x,y,k,q;i<=m;i++)
{
scanf("%d",&q);
if(q==1){
scanf("%d%d%d",&x,&y,&k);
update(x,y,k,1,n,1);
}
if(q==2){
scanf("%d%d",&x,&y);
LL ans=query(x,y,1,n,1);
printf("%lld\n",ans);
}
}
return 0;
}
5.快速幂
#include <iostream>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std;
LL b,k,p;
LL ksm(LL a,LL x)
{
LL ans=1;
while(x){
if(x&1) ans=ans*a%k;
a=a*a%k;
x>>=1;
}
return ans;
}
int main()
{
cin>>b>>p>>k;
printf("%lld^%lld mod %lld=%lld",b,p,k,ksm(b,p)%k);
return 0;
}
6.最小生成树
#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 5000+5
#define maxm 200000+5
using namespace std;
int n,m,fa[maxn],sum=0,ans=0;
struct E{
int u,v,w;
}e[maxm];
int find(int x)
{
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
void hb(int x,int y)
{
fa[find(x)]=find(y);
}
bool cmp(E x,E y)
{
return x.w<y.w;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+1+m,cmp);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
int a=find(e[i].u),b=find(e[i].v),c=e[i].w;
if(a!=b){
hb(a,b);
sum++;
ans+=c;
}
if(sum==n-1) break;
}
cout<<ans;
return 0;
}
7.最大公约数(gcd)+快读
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define maxn 200000+5
using namespace std;
int n,m,p,q;
inline int read(){
int x=0;char ch=getchar();
if(ch>'9'||ch<'0') ch=getchar();
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main (){
n=read();m=read();
int nm=n*m,sum=0;
for(int i=n;i<=m;i++)
{
for(int j=n;j<=m;j++)
{
if(i*j==nm&&gcd(i,j)==n){
sum++;
}
}
}
cout<<sum;
return 0;
}