蒟蒻目前还是提高组选手,模板将会持续更新!
目录:
线段树 对拍 exgcd st 树状数组 树剖 dijsktra spfa tarjan 匈牙利 埃筛 差分树状数组 dinic 快速幂取余
Exgcd
#include<bits/stdc++.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t = x;
x=y;
y=t-a/b*y;
return r;
}
int main()
{
int a,b;
cin>>a>>b;
int x,y;
int p=exgcd(a,b,x,y);
cout<<(x+b)%b<<endl;
return 0;
}
对拍
@echo off
:loop
数据生成器.exe
快速排序.exe
优先队列.exe
fc 快速排序.out 优先队列.out
if not errorlevel 1 goto loop
pause
线段树
#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#define maxn 100010
using namespace std;
struct point{
int l,r;
long long val,mark;
}tr[maxn*4];
int m,n;
int a[maxn];
void buildtree(int x,int l,int r)
{
tr[x].l=l;
tr[x].r=r;
if(l==r)
{
tr[x].val=a[l];
return;
}
int lch=x*2,rch=x*2+1;
int mid=(l+r)/2;
buildtree(lch, l, mid);
buildtree(rch, mid+1, r);
tr[x].val=tr[x*2].val+tr[x*2+1].val;
}
void release(int x)
{
if(tr[x].mark && tr[x].l<tr[x].r)
{
int lch=x*2,rch=x*2+1;
tr[lch].val+=tr[x].mark*((long long)tr[lch].r-tr[lch].l+1);
tr[lch].mark+=tr[x].mark;
tr[rch].val+=tr[x].mark*((long long)tr[rch].r-tr[rch].l+1);
tr[rch].mark+=tr[x].mark;
}
tr[x].mark=0;
}
void modify(int x,int l,int r,long long k)
{
release(x);
if(l<=tr[x].l && tr[x].r<=r)
{
tr[x].val+=k*((long long)tr[x].r-tr[x].l+1);
tr[x].mark+=k;
return;
}
int mid=(tr[x].l+tr[x].r)/2;
if(l<=mid)
modify(x*2, l, r, k);
if(mid<r)
modify(x*2+1, l, r, k);
tr[x].val=tr[x*2].val+tr[x*2+1].val;
}
long long query(int x,int l,int r)
{
release(x);
if(l<=tr[x].l && tr[x].r<=r)
return tr[x].val;
int mid=(tr[x].l+tr[x].r)/2;
long long ans=0;
if(l<=mid)
ans+=query(x*2, l, r);
if(r>mid)
ans+=query(x*2+1, l, r);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
buildtree(1, 1, n);
for(int i=1;i<=m;i++)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x,y;
long long k;
scanf("%d%d%lld",&x,&y,&k);
modify(1, x, y, k);
}
else
{
int x,y;
scanf("%d%d",&x,&y);
printf("%lld
",query(1, x, y));
}
}
}
树剖
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
using namespace std;
#define maxn 600009
int dfn[maxn],cnt,pos[maxn],son[maxn],en[maxn],top[maxn],size[maxn],fa[maxn],deep[maxn];
vector<int> v[maxn];
struct node{
int l,r;
int val,mark;
}tr[maxn*4];
int n,m,r,mod;
int a[maxn];
void dfs(int rt)
{
size[rt]=1;
for(int i=0;i<v[rt].size();i++)
{
int to=v[rt][i];
if(!size[to])
{
fa[to]=rt;
deep[to]=deep[rt]+1;
dfs(to);
size[rt]+=size[to];
if(size[to]>size[son[rt]])son[rt]=to;
}
}
}
void dfs(int x,int tp)
{
top[x]=tp;
cnt++;
pos[x]=cnt;
dfn[cnt]=x;
if(son[x]!=0)dfs(son[x],tp);
for(int i=0;i<v[x].size();i++)
{
int to=v[x][i];
if(!top[to])dfs(to,to);
}
en[x]=cnt;
}
void Build(int x,int l,int r)
{
tr[x].l=l,tr[x].r=r;
if(l==r)
{
tr[x].mark=0;
tr[x].val=a[dfn[l]];
return;
}
int mid=(l+r)>>1;
Build(x*2,l,mid);
Build(x*2+1,mid+1,r);
tr[x].mark=0;
tr[x].val=tr[x*2].val+tr[x*2+1].val;
tr[x].val%=mod;
}
void relese(int x)
{
if(tr[x].mark==0||tr[x].l==tr[x].r)return;
tr[x*2].val+=(tr[x*2].r-tr[x*2].l+1)*tr[x].mark;
tr[x*2].mark+=tr[x].mark;
tr[x*2+1].val+=(tr[x*2+1].r-tr[x*2+1].l+1)*tr[x].mark;
tr[x*2+1].mark+=tr[x].mark;
tr[x*2].val%=mod;
tr[x*2].mark%=mod;
tr[x*2+1].mark%=mod;
tr[x*2+1].val%=mod;
tr[x].mark=0;
}
void Add(int x,int l,int r,int val)
{
if(l<=tr[x].l&&tr[x].r<=r)
{
tr[x].val+=(tr[x].r-tr[x].l+1)*val;
tr[x].val%=mod;
tr[x].mark+=val;
tr[x].mark%=mod;
return;
}
//cout<<x<<" "<<l<<" "<<r<<endl;
relese(x);
int mid=(tr[x].l+tr[x].r)>>1;
if(l<=mid)Add(x*2,l,r,val);
if(r>mid)Add(x*2+1,l,r,val);
tr[x].val=tr[x*2].val+tr[x*2+1].val;
tr[x].val%=mod;
}
int Sum(int x,int l,int r)
{
if(l<=tr[x].l&&tr[x].r<=r)
{
return tr[x].val;
}
relese(x);
int mid=(tr[x].l+tr[x].r)>>1;
int ans=0;
if(l<=mid) ans+=Sum(x*2,l,r);
if(r>mid) ans+=Sum(x*2+1,l,r);
ans%=mod;
return ans;
}
void LCA_add(int x,int y,int val)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])swap(x,y);
Add(1,pos[top[x]],pos[x],val);
x=fa[top[x]];
}
//if(x!=y)
//{
if(pos[x]>pos[y])swap(x,y);
Add(1,pos[x],pos[y],val);
// }
}
int LCA_sum(int x,int y)
{
int res=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])swap(x,y);
res+=Sum(1,pos[top[x]],pos[x]);
res%=mod;
x=fa[top[x]];
}
if(pos[x]>pos[y])swap(x,y);
res+=Sum(1,pos[x],pos[y]);
return res%mod;
}
signed main()
{
scanf("%d%d%d%d",&n,&m,&r,&mod);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(r);
dfs(r,r);
Build(1,1,n);
while(m--)
{
int opt;
scanf("%d",&opt);
if(opt==1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
LCA_add(x,y,z);
}else if(opt==2)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d
",LCA_sum(x,y));
}else if(opt==3)
{
int x,z;
scanf("%d%d",&x,&z);
Add(1,pos[x],en[x],z);
}else
{
int x;
scanf("%d",&x);
printf("%d
",Sum(1,pos[x],en[x]));
}
// for(int i=1;i<=n;i++)
// {
// printf("%d: %d
",i,Sum(1,pos[i],pos[i]));
// }
}
return 0;
}
树状数组
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&-x
int n,m;
const int maxn=500005;
int c[maxn];
int a[maxn];
void Add(int x,int s)
{
while(x<=n)
{
c[x]+=s;
x+=lowbit(x);
}
}
int Get(int x)
{
int ans=0;
while(x)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
Add(i,a[i]);
}
while(m--)
{
int o,x,k;
scanf("%d%d%d",&o,&x,&k);
if(o==1)
{
Add(x,k);
}else
{
printf("%d
",Get(k)-Get(x-1));
}
}
return 0;
}
St表
#include<bits/stdc++.h>
#define ll long long
#define inf 0x7fffffff
using namespace std;
int n,m;
#define maxn 100008
int d[maxn][99];
int a[maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)d[i][0]=a[i];
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++)
{
d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
}
for(int i=1;i<=m;i++)
{
int k=0;
int l,r;
scanf("%d%d",&l,&r);
while(1<<(k+1)<=(r-l+1))k++;
printf("%d
",max(d[l][k],d[r-(1<<k)+1][k]));
}
return 0;
}
Dijkstra
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define maxn 500005
using namespace std;
struct node{
int x,dis;
bool operator < (const node &a)const
{
return dis>a.dis;
}
};
int n,m;
vector<int> son[maxn],v[maxn];
void Set(int prt,int to,int d)
{
son[prt].push_back(to);
v[prt].push_back(d);
}
#define to son[rt.x][i]
int dis[maxn],tim=0;
bool vis[maxn];
priority_queue<node> q;
void dijkstra(int s)
{
for(int i=1;i<=n;i++)
{
dis[i]=inf;
}
memset(vis,0,sizeof(vis));
q.push((node){s,0});
dis[s]=0;
while(!q.empty())
{
node rt=q.top();
q.pop();
if(vis[rt.x])
{
continue;
}
vis[rt.x]=1;
for(int i=0;i<son[rt.x].size();i++)
{
if(dis[to]>dis[rt.x]+v[rt.x][i])
{
dis[to]=dis[rt.x]+v[rt.x][i];
q.push((node){to,dis[to]});
}
}
}
}
int main()
{
int s;
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);
Set(x,y,z);
}
dijkstra(s);
for(int i=1;i<=n;i++)
{
printf("%d ",dis[i]);
}
return 0;
}
Spfa
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
#define maxn 10009
int n,m,s;
vector<int> son[maxn],v[maxn];
void Add(int x,int y,int val)
{
son[x].push_back(y);
v[x].push_back(val);
}
struct node{
int x;
int dis;
};
int dis[maxn];
void spfa(int s)
{
for(int i=1;i<=n;i++)dis[i]=inf;
queue<node> q;
q.push((node){s,0});
dis[s]=0;
while(!q.empty())
{
node now=q.front();
q.pop();
for(int i=0;i<son[now.x].size();i++)
{
int to=son[now.x][i];
if(dis[to]>dis[now.x]+v[now.x][i])
{
dis[to]=dis[now.x]+v[now.x][i];
q.push((node){to,dis[to]});
}
}
}
}
signed 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);
}
spfa(s);
for(int i=1;i<=n;i++)
{
printf("%d ",dis[i]);
}
return 0;
}
Tarjan
int n,m;
#define maxn 10009
vector<int> son[maxn];
int tim,size[maxn],belong[maxn],scc_cnt,cnt;
bool bein[maxn];
int st[maxn];
int dfn[maxn],low[maxn];
void Tarjan(int rt)
{
dfn[rt]=low[rt]=++tim;
st[++cnt]=rt;
for(int i=0;i<son[rt].size();i++)
{
int to=son[rt][i];
if(!dfn[to])//正向边
{
Tarjan(to);
low[rt]=min(low[rt],low[to]);
}else if(!belong[to])//反向边
{
low[rt]=min(low[rt],dfn[to]);//能不能取到一个更早的点
}
}
if(dfn[rt]==low[rt])
{
//关键节点!!
scc_cnt++;
int k;
do{
k=st[cnt--];
belong[k]=scc_cnt;
size[scc_cnt]++;
}while(k!=rt);
}
}
二分图匹配
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
int n,m,e;
#define maxn 3009
vector<int> son[maxn];
int hav[maxn];
int vis[maxn];
int timemark=0;
bool dfs(int x)
{
for(int i=0;i<son[x].size();i++)
{
int to=son[x][i];
if(vis[to]==timemark)continue;
vis[to]=timemark;
if(!hav[to]||dfs(hav[to]))
{
hav[to]=x;
return 1;
}
}
return 0;
}
signed main()
{
scanf("%d%d%d",&n,&m,&e);
while(e--)
{
int u,v;
scanf("%d%d",&u,&v);
if(v>m||u>n)continue;
v+=1009;//!!!
son[u].push_back(v);
son[v].push_back(u);
}
int s=n;
for(int i=1;i<=n;i++)
{
timemark++;
if(!dfs(i))s--;
}
printf("%d
",s);
return 0;
}
线性素数筛
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
using namespace std;
bool p[10000000];
signed main()
{
int n,m;
memset(p,1,sizeof(p));
p[1]=0;
scanf("%d%d",&n,&m);
for(int i=2;i<=sqrt(10000000);i++)
{
if(p[i])
{
for(int j=i*2;j<=10000000;j+=i)p[j]=0;
}
}
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
if(p[x])printf("Yes
");
else printf("No
");
}
return 0;
}
差分树状数组
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&-x
int n,m;
const int maxn=500005;
int c[maxn];
int a[maxn];
void Add(int x,int s)
{
while(x<=n)
{
c[x]+=s;
x+=lowbit(x);
}
}
int Get(int x)
{
int ans=0;
while(x)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
Add(i,a[i]);
Add(i+1,-a[i]);
}
while(m--)
{
int o;
scanf("%d",&o);
if(o==1)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
Add(x,k);
Add(y+1,-k);
}else
{
int k;
scanf("%d",&k);
printf("%d
",Get(k));
}
}
return 0;
}
dinic
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
using namespace std;
#define maxn 10009
#define maxm 100009
struct node{
int val,to;
int rev;//rev表示反边在to的vector当中下标是几
node(int _to,int _val,int _rev)
{
to=_to;
val=_val;
rev=_rev;
}
};
vector<node> son[maxn];
int d[maxn];
int n,m,s,t;
void add(int x,int y,int w)
{
son[x].push_back(node(y,w,son[y].size()));
son[y].push_back(node(x,0,son[x].size()-1));
}
int ans=0;
bool bfs()
{
memset(d,-1,sizeof(d));
queue<int> q;
q.push(s);
d[s]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<son[x].size();i++)
{
int y=son[x][i].to;
if(d[y]==-1 && son[x][i].val)
{
q.push(y);
d[y]=d[x]+1;
}
}
}
if(d[t]==-1)return 0;
return 1;
}
int dfs(int x,int low)//x 表示当前节点,low表示当前到x的最小参量
{
if(x==t||low==0) return low;
int s=0;
for(int i=0;i<son[x].size();i++)
{
int y=son[x][i].to;
int rev=son[x][i].rev;
if(d[y]==d[x]+1&&son[x][i].val>0)
{
int a=dfs(y,min(low,son[x][i].val));//当前
son[x][i].val-=a;
son[y][rev].val+=a;
low-=a;
s+=a;
if(low==0) return s;
}
}
if(low!=0)//流到x的流量会有冗余,在这一轮dfs之后就在不会到x了
{
d[x]=-1;
}
return s;
}
void dinic()
{
while(bfs())
{
ans+=dfs(s,inf);
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
//dinic
dinic();
printf("%d
",ans);
return 0;
}
快速幂取余
#include<bits/stdc++.h>
#define ll long long
ll d,p,k;
ll cal(ll x,ll y)
{
ll ans=1;
for(;y;x=x*x%k,y>>=1)
if(y&1)ans=ans*x%k;
return ans;
}
using namespace std;
int main()
{
cin>>d>>p>>k;
cout<<d<<"^"<<p<<" mod "<<k<<"="<<cal(d,p)%k<<endl;
return 0;
}