动态更新-算法模版合集
图论
最大流
int s=1995,t=1996;
struct gg {
int u,v,w,next;
}side[maxn*2];
int head[maxn],cnt=1,maxflow,cur[maxn],rk[maxn];
using namespace std;
void insert(int u,int v,int w) {
struct gg a={u,v,w,head[u]};side[++cnt]=a;head[u]=cnt;
};
bool bfs() {
memset(rk,0,sizeof(rk));rk[s]=1;
queue<int>q;q.push(s);
while(!q.empty()) {
int now=q.front();q.pop();
for(int i=head[now];i;i=side[i].next) {
int v=side[i].v,w=side[i].w;//w为容量
if(!w||rk[v])continue;
rk[v]=rk[now]+1;
q.push(v);
}
}
if(rk[t])return 1;//走得到
return 0;
}
int dfs(int now,int flow) {//flow为上一个点能传到这里的流量
if(now==t)return flow;
int tot=0;
for(int &i=cur[now];i;i=side[i].next) {//当前弧优化
int v=side[i].v,w=side[i].w;
if(!w||rk[v]!=rk[now]+1)continue;
int sent=dfs(v,min(flow,w));//sent为当前增广的流量
tot+=sent;//累计答案
flow-=sent;side[i].w-=sent;side[i^1].w+=sent;//更新残余网络
}
return tot;
}
void dinic() {
while(bfs()) {
memcpy(cur,head,sizeof(head));//当前弧优化
maxflow+=dfs(s,inf);
}
}
单源最短路
typedef pair<ll,int> pli;
priority_queue<pli,vector<pli>,greater<pli> >q;
void dij() {
memset(dis,0x3f,sizeof(dis));
dis[0]=0;q.push(make_pair(dis[0],0));
while(!q.empty()) {
int now=q.top().second;ll val=q.top().first;q.pop();
if(val>dis[now])continue;
for(int i=head[now];i;i=side[i].next) {
int v=side[i].v;
if(dis[now]+side[i].w<dis[v]) {
dis[v]=dis[now]+side[i].w;q.push(make_pair(dis[v],v));
}
}
}
}
笛卡尔树
for(int i=1;i<=n;i++) {
int k=cnt;
while(k>0&&h[stk[k]]>h[i])k--;
if(k)rs[stk[k]]=i;
if(k<cnt)ls[i]=stk[k+1];
stk[++k]=i;
cnt=k;
}
字符串
KMP
nex[0]=-1;int i=0,j=-1;
scanf("%d%s",&n,s);
while(i<n) {
if(j==-1||s[i]==s[j])i++,j++,nex[i]=j;
else j=nex[j];
}
哈希
long long h1[maxn],h2[maxn],p1[maxn],p2[maxn],tmp1,tmp2;
int base[2]={233,19260817},mod[2]={(int)1e9+7,(int)1e9+9};
int get1(int l,int r) {
return ((h1[r]-h1[l-1]*p1[r-l+1])%mod[0]+mod[0])%mod[0];
}
int get2(int l,int r) {
return ((h2[r]-h2[l-1]*p2[r-l+1])%mod[1]+mod[1])%mod[1];
}
void init_hash() {
p1[1]=base[0],p2[1]=base[1];
for(int i=2;i<=200000;i++) {
p1[i]=p1[i-1]*base[0];p1[i]%=mod[0];
p2[i]=p2[i-1]*base[1];p2[i]%=mod[1];
}
for(int i=1;i<=n;i++) {
h1[i]=h1[i-1]*base[0]+S[i];h1[i]%=mod[0];
h2[i]=h2[i-1]*base[1]+S[i];h2[i]%=mod[1];
}
}
void solve_hash(){
tmp1=0,tmp2=0;
for(int i=1;i<=lenp;i++) {
tmp1=tmp1*base[0]+T[i];tmp1%=mod[0];
tmp2=tmp2*base[1]+T[i];tmp2%=mod[1];
}
for(int l=1,r=lenp;r<=n;l++,r++) {
if(get1(l,r)==tmp1&&get2(l,r)==tmp2) {
s[++cn]={l,r};
}
}
}
数据结构
带乘法tag的带权并查集
int get(int x) {
if(x==fa[x])return x;
int tmp=get(fa[x]);
if(fa[x]!=tmp)w[x]=w[x]*w[fa[x]]%mod;
return fa[x]=tmp;
}
void uni(int x,int y) {//y合并到x
w[y]=w[y]*ksm(w[x],mod-2)%mod;
fa[y]=x;
}