ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

带修维护两点间简单路径能经过的最小点权,n,q<=1e5

可以用圆方树重构图为树:对每个点双联通分量新建一个点表示,到对应点连边,割边保留,删去其余边,每个新建的点维护所有孩子的最小值,外加树链剖分查询链最值,特判lca的父亲。

#include<bits/stdc++.h>
const int N=100007,inf=0x7fffffff;
char ib[N*100],*ip=ib,ob[N*20],*op=ob;
int _(){
    int x=0;
    while(*ip<48)++ip;
    while(*ip>47)x=x*10+*ip++-48;
    return x;
}
void pr(int x){
    int ss[15],sp=0;
    do ss[++sp]=x%10;while(x/=10);
    while(sp)*op++=ss[sp--]+48;
    *op++=10;
}
int n,m,q,v0[N],_n;
int fa[N*2],sz[N*2],son[N*2],dep[N*2],top[N*2],id[N*2],idp=0;
std::vector<int>e[N*2],E[N];
int mx,tr[555555];
void f1(int w,int pa){
    dep[w]=dep[fa[w]=pa]+(sz[w]=1);
    for(int i=0;i<e[w].size();++i){
        int u=e[w][i];
        f1(u,w);
        sz[w]+=sz[u];
        if(sz[u]>sz[son[w]])son[w]=u;
    }
}
void f2(int w,int tp){
    top[w]=tp;
    id[w]=++idp;
    if(son[w])f2(son[w],tp);
    for(int i=0;i<e[w].size();++i){
        int u=e[w][i];
        if(u!=son[w])f2(u,u);
    }
}
struct dheap{
    std::priority_queue<int,std::vector<int>,std::greater<int> >q,qd;
    void ins(int x){q.push(x);}
    void del(int x){qd.push(x);}
    int top(){
        if(q.size()==qd.size())return inf;
        while(qd.size()&&q.top()==qd.top())q.pop(),qd.pop();
        return q.top();
    }
    void pop(){
        while(qd.size()&&q.top()==qd.top())q.pop(),qd.pop();
        q.pop();
    }
}ds[N*2];
void mins(int&a,int b){if(a>b)a=b;}
int min(int a,int b){return a<b?a:b;}
int qmn(int L,int R){
    int v=inf;
    for(L+=mx-1,R+=mx+1;R-L!=1;L>>=1,R>>=1){
        if(~L&1)mins(v,tr[L+1]);
        if(R&1)mins(v,tr[R-1]);
    }
    return v;
}
void set(int x,int y){
    tr[x+=mx]=y;
    for(x>>=1;x;x>>=1){
        int z=min(tr[x<<1],tr[(x<<1)+1]);
        if(z!=tr[x])tr[x]=z;
        else break;
    }
}
void que(int x,int y){
    int a=top[x],b=top[y],v=inf;
    while(a!=b){
        if(dep[a]<dep[b])std::swap(x,y),std::swap(a,b);
        mins(v,qmn(id[a],id[x]));
        x=fa[a],a=top[x];
    }
    if(dep[x]<dep[y])std::swap(x,y);
    mins(v,qmn(id[y],id[x]));
    if(y>n&&fa[y])mins(v,v0[fa[y]]);
    pr(v);
}
void modify(int x,int y){
    int f=fa[x];
    if(f>n){
        ds[f].del(v0[x]);
        ds[f].ins(y);
        set(id[f],ds[f].top());
    }
    v0[x]=y;
    set(id[x],y);
}
int dfn[N],low[N],tk,ss[N],sp=0;
void tj(int w,int pa){
    dfn[w]=low[w]=++tk;
    ss[++sp]=w;
    for(int i=0;i<E[w].size();++i){
        int u=E[w][i];
        if(u==pa)continue;
        if(!dfn[u]){
            tj(u,w);
            mins(low[w],low[u]);
            if(dfn[w]<low[u])e[w].push_back(ss[sp--]);
            else if(dfn[w]<=low[u]){
                v0[++_n]=inf;
                while(1){
                    int x=ss[sp--];
                    ds[_n].ins(v0[x]);
                    e[_n].push_back(x);
                    if(x==u)break;
                }
                e[w].push_back(_n);
            }
        }else mins(low[w],dfn[u]);
    }
}
int main(){
    fread(ib,1,sizeof(ib),stdin);
    n=_();m=_();q=_();
    for(int i=1;i<=n;++i)v0[i]=_();
    for(int i=0,a,b;i<m;++i){
        a=_();b=_();
        E[a].push_back(b);
        E[b].push_back(a);
    }
    _n=n;
    tj(1,0);
    f1(1,0);f2(1,1);
    for(mx=1;mx<=_n+5;mx<<=1);
    for(int i=1;i<=n;++i)tr[mx+id[i]]=v0[i];
    for(int i=n+1;i<=_n;++i)tr[mx+id[i]]=ds[i].top();
    for(int i=mx-1;i;--i)tr[i]=min(tr[i<<1],tr[(i<<1)+1]);
    for(int i=0,o,a,b;i<q;++i){
        o=_();a=_();b=_();
        if(o=='A'-48)que(a,b);
        else modify(a,b);
    }
    fwrite(ob,1,op-ob,stdout);
    return 0;
}
View Code

 

posted on 2017-08-15 15:46  nul  阅读(249)  评论(0编辑  收藏  举报