Templates
Posted blogofchc1234567890
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Templates相关的知识,希望对你有一定的参考价值。
Game theory
Nim
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,x,res=0;
scanf("%d",&n);
while(n--){
scanf("%d",&x);
res^=x;
}
puts(res==0?"No":"Yes");
}
return 0;
}
SG function
Graph theory
SPFA
void spfa(int start){
for(int i=1;i<=n;i++)dis[i]=INF,vis[i]=0;
dis[start]=0;
q[qhead=qtail=1]=start;
while(qhead<=qtail){
int u=q[qhead++];
vis[u]=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(dis[u]+e[i].w<dis[v]){
dis[v]=dis[u]+e[i].w;
if(!vis[v]){
vis[v]=1;
q[++qtail]=v;
}
}
}
}
}
SPFA check negative cycles
void spfa(){
for(int i=1;i<=n;i++)cnt[i]=vis[i]=0,dis[i]=-INF;
dis[1]=0;
queue<int> q;
q.push(1);
while(!q.empty()){
int u=q.top();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
D w=e[i].a*dis[u]+e[i].b;
if(w>dis[v]&&cnt[v]<=n){
dis[v]=w;
if(++cnt[v]>n)dis[v]=INF;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
}
Dijkstra
void dijkstra(int st){
for(int i=1;i<=n;i++){
dis[i]=INF;
vis[i]=0;
}
dis[st]=0;
priority_queue<P,vector<P>,greater<P> > q;
q.push(P(0,st));
while(!q.empty()){
int u=q.top().second,v;
q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].next){
v=e[i].to;
if(dis[u]+e[i].w<dis[v]&&!vis[v]){
dis[v]=dis[u]+e[i].w;
q.push(P(dis[v],v));
}
}
}
}
Floyd
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
Floyd求路径最值限制问题
例:过路费
有一天你来到了一个奇怪的国家,它有 (N) 个城市,城市之间有若干条双向道路连接,每条道路都有一定的费用,经过城市也要一定的费用。从一个城市到达另一个城市的总花费为路径上费用最大的城市费用(包括起点和终点)加上路径上所有的道路的费用。给出 (Q) 次询问,分别回答每次询问中两城市间的最少花费。保证城市之间可以互达。
#include<bits/stdc++.h>
using namespace std;
const int maxn=303,INF=0x3f3f3f3f;
int n,m,Q,p[maxn],a[maxn],g[maxn][maxn],dp[maxn][maxn];
bool cmp(int x,int y){return a[x]<a[y];}
void floyd(int k){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
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++){
for(int j=1;j<=n;j++)dp[i][j]=g[i][j]=INF;
g[i][i]=0;
p[i]=i;
}
sort(p+1,p+n+1,cmp);
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
g[u][v]=g[v][u]=min(g[u][v],w);
}
for(int l=1,r=1;l<=n;l=r){
for(;r<=n&&a[p[l]]==a[p[r]];r++){
floyd(p[r]);
}
for(int _i=1;_i<r;_i++){
int i=p[_i];
for(int _j=1;_j<r;_j++){
int j=p[_j];
dp[i][j]=min(dp[i][j],g[i][j]+a[p[l]]);
}
}
}
scanf("%d",&Q);
while(Q--){
int x,y;
scanf("%d%d",&x,&y);
printf("%d
",dp[x][y]);
}
return 0;
}
SCC
void tarjan(int u){
dfn[u]=low[u]=++cntdfn;
stk[++top]=u;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!incyc[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
numcyc[++cntcyc]=0;
int x;
do{
x=stk[top];
top--;
numcyc[cntcyc]++;
incyc[x]=cntcyc;
}while(x!=u);
}
}
void getcyc(){
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
}
topological-sort
void topsort(){
queue<int> q;
for(int i=1;i<=n;i++){
if(indeg[i]==0){
q.push(i);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(--indeg[v]==0){
q.push(v);
}
}
}
}
bipartite-graph max-match (Hungary algorithm)
bool dfs(int u){
for(int i=0;i<int(g[u].size());i++){
int v=g[u][i];
if(vis[v])continue;
vis[v]=1;
if(!c[v]||dfs(c[v])){
d[u]=v;
c[v]=u;
return 1;
}
}
return 0;
}
int match(){
int ret=0;
for(int i=1;i<=n1;i++){
for(int j=1;j<=n2;j++)vis[j]=0;
if(dfs(i))ret++;
}
return ret;
}
int main(){
scanf("%d%d%d",&n1,&n2,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
printf("%d
",match());
return 0;
}
bipartite-graph max-match in minimum lexicographic order (Hungary algorithm)
bool dfs(int u){
for(int i=0;i<int(g[u].size());i++){
int v=g[u][i];
if(vis[v])continue;
vis[v]=1;
if(!c[v]||dfs(c[v])){
d[u]=v;
c[v]=u;
return 1;
}
}
return 0;
}
int match(){
int ret=0;
for(int i=n1;i>=1;i--){
for(int j=1;j<=n2;j++)vis[j]=0;
if(dfs(i))ret++;
}
return ret;
}
int main(){
scanf("%d%d%d",&n1,&n2,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
for(int i=1;i<=n1;i++)sort(g[i].begin(),g[i].end());
printf("%d
",match());
return 0;
}
bipartite-graph perfect-match in maximum weight (KM-algorithm)
bool dfs(int u){
visd[u]=1;
for(int v=1;v<=n;v++){
int tmp=ld[u]+lc[v]-g[u][v];
if(!visc[v]&&!tmp){
visc[v]=1;
if(!c[v]||dfs(c[v])){
c[v]=u;
return 1;
}
}
else if(tmp<slack[v]){
slack[v]=tmp;
}
}
return 0;
}
int km(){
for(int i=1;i<=n;i++){
c[i]=lc[i]=ld[i]=0;
for(int j=1;j<=n;j++){
ld[i]=max(ld[i],g[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)slack[j]=INF;
while(1){
for(int j=1;j<=n;j++)visc[j]=visd[j]=0;
if(dfs(i))break;
int res=INF;
for(int v=1;v<=n;v++){
if(!visc[v]){
res=min(res,slack[v]);
}
}
for(int u=1;u<=n;u++){
if(visd[u]){
ld[u]-=res;
}
}
for(int v=1;v<=n;v++){
if(visc[v]){
lc[v]+=res;
}
else{
slack[v]-=res;
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++)ans+=ld[i]+lc[i];
return ans;
}
network-flow (Dinic)
bool bfs(){
for(int i=1;i<=n;i++)dep[i]=0,head1[i]=head[i];
dep[s]=1;
int *qhead=q,*qtail=q;
*qtail++=s;
while(qhead!=qtail){
int u=*qhead++;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(e[i].w&&dep[v]==0){
dep[v]=dep[u]+1;
*qtail++=v;
}
}
}
return dep[t]!=0;
}
int dfs(int u,int low){
if(low==0||u==t)return low;
int flow=0;
for(int &i=head1[u];~i;i=e[i].next){
int v=e[i].to;
if(e[i].w&&dep[v]==dep[u]+1){
int tmp=dfs(v,min(low,e[i].w));
if(tmp==0)dep[v]=0;
else{
flow+=tmp;
low-=tmp;
e[i].w-=tmp;
e[i^1].w+=tmp;
if(low==0)break;
}
}
}
return flow;
}
int dinic(){
int ans=0;
while(bfs())ans+=dfs(s,INF);
return ans;
}
int main(){
int m;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=n;i++)head[i]=-1;
cnte=-1;
while(m--){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
printf("%d",dinic());
return 0;
}
network-flow (SPFA+EK)
bool spfa(){
for(int i=1;i<=n;i++)flow[i]=dis[i]=INF,vis[i]=0;
pre[t]=-1;
dis[s]=0;
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(e[i].w>0&&dis[u]+e[i].cost<dis[v]){
dis[v]=dis[u]+e[i].cost;
pre[v]=u;
edg[v]=i;
flow[v]=min(flow[u],e[i].w);
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return pre[t]!=-1;
}
void micmxf(){
while(spfa()){
int x=t;
while(x!=s){
e[edg[x]].w-=flow[t];
e[edg[x]^1].w+=flow[t];
x=pre[x];
}
maxflow+=flow[t];
mincost+=flow[t]*dis[t];
}
}
int main(){
int m;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=0;i<=n;i++)head[i]=-1;
cnte=-1;
for(int i=1;i<=m;i++){
int u,v,w,cost;
scanf("%d%d%d%d",&u,&v,&w,&cost);
add(u,v,w,cost);
add(v,u,0,-cost);
}
micmxf();
printf("%d %d
",maxflow,mincost);
return 0;
}
MST (Prim)
void prim(){
for(int i=1;i<=n;i++)dis[i]=INT_MAX;
priority_queue<pii,vector<pii>,greater<pii> > q;
q.push(make_pair(0,1));
while(!q.empty()){
int d=q.top().first,u=q.top().second;
q.pop();
if(vis[u])continue;
ans+=d;
vis[u]=1;
cnt++;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(dis[v]>e[i].w&&!vis[v]){
dis[v]=e[i].w;
q.push(make_pair(dis[v],v));
}
}
}
}
MST (Kruskal)
void kruskal(){
sort(e+1,e+m+1);
ufset s(n);
for(int i=1;i<=m;i++){
int u=e[i].from,v=e[i].to;
if(s.same(u,v))continue;
ans+=e[i].w;
s.Union(u,v);
if(++tot==n-1)break;
}
}
Strictly second-best?MST
#include<bits/stdc++.h>
#define maxn 100003
#define maxm 300003
#define INF 100000000000000000ll
using namespace std;
typedef long long D;
D n,m,lg[maxn];
namespace G{
struct edge{
D from,to,w;
bool vis;
bool operator <(const edge& x)const{return w<x.w;}
}e[maxm];
D cnte;
void add(D u,D v,D w){e[++cnte]=(edge){u,v,w,0};}
}
namespace MST{
struct edge{
D to,next,w;
}e[maxn<<1];
D head[maxn],cnte,dep[maxn],fa[maxn][23],mx[maxn][23][2];
void add(D u,D v,D w){e[++cnte]=(edge){v,head[u],w},head[u]=cnte;}
void calc(D &X0,D &X1,D Y0,D Y1,D Z0,D Z1){
X0=max(Y0,Z0);
if(Y0!=Z0)X1=max(min(Y0,Z0),max(Y1,Z1));
else X1=max(Y1,Z1);
}
void init(D u,D last){
fa[u][0]=last;
dep[u]=dep[last]+1;
for(D i=1;(1<<i)<=dep[u];i++){
D up=fa[u][i-1];
fa[u][i]=fa[up][i-1];
calc(mx[u][i][0],mx[u][i][1],mx[u][i-1][0],mx[u][i-1][1],mx[up][i-1][0],mx[up][i-1][1]);
}
for(D i=head[u];i;i=e[i].next){
D v=e[i].to;
if(v==last)continue;
mx[v][0][0]=e[i].w;
init(v,u);
}
}
D lca(D x,D y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y]){
x=fa[x][lg[dep[x]-dep[y]]];
}
if(x==y)return x;
for(D i=lg[dep[x]];i>=0;i--){
if(fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
D query(D x,D y,D w){
D l=lca(x,y);
D ans0=0,ans1=0;
while(x!=l){
calc(ans0,ans1,ans0,ans1,mx[x][lg[dep[x]-dep[l]]][0],mx[x][lg[dep[x]-dep[l]]][1]);
x=fa[x][lg[dep[x]-dep[l]]];
}
while(y!=l){
calc(ans0,ans1,ans0,ans1,mx[y][lg[dep[y]-dep[l]]][0],mx[y][lg[dep[y]-dep[l]]][1]);
y=fa[y][lg[dep[y]-dep[l]]];
}
if(w!=ans0)return w-ans0;
if(ans1)return w-ans1;
return INF;
}
}
D f[maxn];
D find(D x){
if(x!=f[x])f[x]=find(f[x]);
return f[x];
}
D kruskal(){
D cnt=0,ret=0;
sort(G::e+1,G::e+m+1);
for(D i=1;i<=n;i++)f[i]=i;
for(D i=1;i<=m;i++){
D u=G::e[i].from,v=G::e[i].to,fu=find(u),fv=find(v);
if(fu!=fv){
f[fu]=fv;
ret+=G::e[i].w;
G::e[i].vis=1;
MST::add(u,v,G::e[i].w);
MST::add(v,u,G::e[i].w);
cnt++;
if(cnt>=n)break;
}
}
return ret;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(D i=1;i<=m;i++){
D u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
G::add(u,v,w);
}
D ans1=kruskal(),ans2=INF;
for(D i=2;i<maxn;i++)lg[i]=lg[i-1]+((1<<(lg[i-1]+1))==i);
MST::init(1,0);
for(D i=1;i<=m;i++){
if(!G::e[i].vis){
D u=G::e[i].from,v=G::e[i].to;
ans2=min(ans2,MST::query(u,v,G::e[i].w));
}
}
printf("%lld
",ans1+ans2);
return 0;
}
LCA (Heavy-light decomposition)
void initdep(int u,int last){
sz[u]=1;
fa[u]=last;
int mx=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u])continue;
dep[v]=dep[u]+1;
initdep(v,u);
sz[u]+=sz[v];
if(sz[v]>mx)mx=sz[v],son[u]=v;
}
}
void initdfn(int u,int tp){
dfn[u]=++cntdfn;
num[cntdfn]=u;
top[u]=tp;
if(son[u]){
initdfn(son[u],tp);
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==son[u])continue;
initdfn(v,v);
}
rig[u]=cntdfn;
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
return y;
}
LCA (ST RMQ)
void init(int u,int last){
st[++cntdfn][0]=u;
dfn[u]=cntdfn;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==last)continue;
dep[v]=dep[u]+1;
init(v,u);
st[++cntdfn][0]=u;
}
}
int work(int x,int y){return dep[x]<dep[y]?x:y;}
void initst(){
for(int len=1;(1<<len)<=cntdfn;len++){
for(int i=1;i+(1<<len)-1<=cntdfn;i++){
st[i][len]=work(st[i][len-1],st[i+(1<<(len-1))][len-1]);
}
}
}
int lca(int x,int y){
if(dfn[x]>dfn[y])swap(x,y);
int tmp=lg[dfn[y]-dfn[x]+1];
return work(st[dfn[x]][tmp],st[dfn[y]-(1<<tmp)+1][tmp]);
}
LCA (doubling)
void init(int u){
for(int i=1;(1<<i)<=dep[u];i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u][0])continue;
fa[v][0]=u;
dep[v]=dep[u]+1;
init(v);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])x=fa[x][lg[dep[x]-dep[y]]];
if(x==y)return x;
for(int i=lg[dep[x]];i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
Virtual tree
#include<bits/stdc++.h>
using namespace std;
const int maxn=250003,maxm=500003,INF=0x3f3f3f3f;
struct edge{int to,next,w;}e[maxn<<1];
int head[maxn],cnte;
void add(int u,int v,int w){e[++cnte].to=v,e[cnte].w=w,e[cnte].next=head[u],head[u]=cnte;}
int n,lg[maxn],fa[maxn][23],cntdfn,dfn[maxn],rig[maxn],dep[maxn],p[maxn<<2],
mi[maxn],stk[maxn],top;
long long dp[maxn];
bool vis[maxn];
void init(int u,int last){
dfn[u]=++cntdfn;
fa[u][0]=last;
for(int i=1;(1<<i)<=dep[u];i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==last)continue;
dep[v]=dep[u]+1;
mi[v]=min(mi[u],e[i].w);
init(v,u);
}
rig[u]=++cntdfn;
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])x=fa[x][lg[dep[x]-dep[y]]];
if(x==y)return x;
for(int i=lg[dep[x]];i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
bool cmp(int x,int y){return (x>0?dfn[x]:rig[-x])<(y>0?dfn[y]:rig[-y]);}
int main(){
for(int i=2;i<maxn;i++)lg[i]=lg[i-1]+((1<<(lg[i-1]+1))==i);
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
mi[1]=INF;
init(1,0);
int Q;
scanf("%d",&Q);
while(Q--){
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++)scanf("%d",p+i),vis[p[i]]=1,dp[p[i]]=mi[p[i]];
sort(p+1,p+m+1,cmp);
for(int i=2;i<=m;i++){
int l=lca(p[i-1],p[i]);
if(vis[l])continue;
vis[l]=1;
p[++m]=l;
}
for(int i=m;i>=1;i--)p[++m]=-p[i];
if(!vis[1]){
p[++m]=1,p[++m]=-1;
vis[1]=1;
}
sort(p+1,p+m+1,cmp);
top=0;
for(int i=1;i<m;i++){
if(p[i]>0){
stk[++top]=p[i];
}
else{
int u=stk[top--],last=stk[top];
dp[last]+=min(dp[u],(long long)mi[u]);
vis[u]=0,dp[u]=0;
}
}
printf("%lld
",dp[1]);
vis[1]=0,dp[1]=0;
}
return 0;
}
Tree-plus-cycle (contaning multiple edges)
bool init(int u,int laste){
stk[++top][0]=u,stk[top][1]=laste;
instk[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(flip(i)==laste)continue;
if(instk[v]){
int x,y=i;
do{
x=stk[top][0];
cyc[++cnt][0]=x,cyc[cnt][1]=y;
incyc[x]=1;
y=stk[top][1];
top--;
}while(x!=v);
return 1;
}
if(init(v,i))return 1;
}
top--;
return 0;
}
Heavy-light-decomposition
namespace SEG{
struct node{
long long sum,z;
}t[maxn<<2];
void pushdown(int p,int l,int r){
if(l==r){t[p].z=0;return;}
if(t[p].z){
int mid=(l+r)>>1;
PlusEqual(t[p<<1].sum,L(t[p].z*(mid-l+1)));
PlusEqual(t[p<<1|1].sum,L(t[p].z*(r-mid)));
PlusEqual(t[p<<1].z,t[p].z);
PlusEqual(t[p<<1|1].z,t[p].z);
t[p].z=0;
}
}
void pushup(int p,int l,int r){
t[p].sum=L(t[p<<1].sum+t[p<<1|1].sum);
}
void build(int p,int l,int r){
t[p].z=0;
if(l==r){
t[p].sum=a[num[l]];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p,l,r);
}
void change(int p,int l,int r,int pos,long long k){
pushdown(p,l,r);
if(l==r){
PlusEqual(t[p].sum,k);
return;
}
int mid=(l+r)>>1;
if(pos<=mid)change(p<<1,l,mid,pos,k);
else change(p<<1|1,mid+1,r,pos,k);
pushup(p,l,r);
}
void change(int p,int l,int r,int seg_l,int seg_r,long long k){
pushdown(p,l,r);
if(seg_l<=l&&r<=seg_r){
PlusEqual(t[p].sum,L(k*(r-l+1)));
t[p].z=k;
return;
}
int mid=(l+r)>>1;
if(seg_l<=mid)change(p<<1,l,mid,seg_l,seg_r,k);
if(seg_r>mid)change(p<<1|1,mid+1,r,seg_l,seg_r,k);
pushup(p,l,r);
}
long long query(int p,int l,int r,int seg_l,int seg_r){
pushdown(p,l,r);
if(seg_l<=l&&r<=seg_r){
return t[p].sum;
}
int mid=(l+r)>>1;
long long ret=0;
if(seg_l<=mid)PlusEqual(ret,query(p<<1,l,mid,seg_l,seg_r));
if(seg_r>mid)PlusEqual(ret,query(p<<1|1,mid+1,r,seg_l,seg_r));
return ret;
}
}
void initdep(int u,int last,int depth){
fa[u]=last;
dep[u]=depth;
sz[u]=1;
int mxsz=0;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa[u])continue;
initdep(v,u,depth+1);
sz[u]+=sz[v];
if(sz[v]>mxsz)mxsz=sz[v],son[u]=v;
}
}
void initdfn(int u,int tp){
dfn[u]=++cntdfn;
num[cntdfn]=u;
top[u]=tp;
if(son[u]){
initdfn(son[u],tp);
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==son[u])continue;
initdfn(v,v);
}
}
rig[u]=cntdfn;
}
void change(int u,long long w){
SEG::change(1,1,n,dfn[u],w);
}
void change(int x,int y,long long w){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
SEG::change(1,1,n,dfn[top[x]],dfn[x],w);
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
SEG::change(1,1,n,dfn[y],dfn[x],w);
}
void changesub(int u,long long w){
SEG::change(1,1,n,dfn[u],rig[u],w);
}
long long query(int x,int y){
long long ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
PlusEqual(ans,SEG::query(1,1,n,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
PlusEqual(ans,SEG::query(1,1,n,dfn[y],dfn[x]));
return ans;
}
long long querysub(int x){
return SEG::query(1,1,n,dfn[x],rig[x]);
}
以上是关于Templates的主要内容,如果未能解决你的问题,请参考以下文章