码迷,mamicode.com
首页 > 其他好文 > 详细

Templates

时间:2019-10-12 22:26:29      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:typedef   check   lld   names   sum   game   shu   spfa   rom   

技术图片

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\n",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\n",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\n",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\n",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\n",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

例:[SDOI2011]消耗战

#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\n",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

标签:typedef   check   lld   names   sum   game   shu   spfa   rom   

原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/11663963.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!