zoukankan      html  css  js  c++  java
  • [CodeForces 487E]Tourists

    Link

    Description

    (n)个点,(m)条边的无向连通图,每个点有点权。

    有两种操作:

    • 修改某个点的点权。
    • 询问两点间所有简单路径上点权最小值。

    Solution

    建出圆方树。令方点点权为相邻圆点点权的最小值。那么现在询问就变成查询路径最小值,可以用树剖+线段树解决。

    对于修改,如果修改某个点权值,那么它周围的所有方点权值都要修改,可以被卡成( ext O(n))

    所以改一下思路,考虑到圆方树是一棵树,可以令方点点权为其儿子圆点点权的最小值。这样,修改一个圆点,只需要顺带修改其父亲方点的点权即可。

    对于每方点,用一个multiset维护所有儿子圆点的权值。

    值得注意的是,如果查询时两点lca是方点,那还要查询其父亲圆点的权值。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline int read(){//be careful for long long!
        register int x=0,f=1;register char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
        return f?x:-x;
    }
     
    const int N=1e5+10;
    int n,m,q,w[N<<1],cnt,dfc,dfn[N<<1],low[N],stk[N],tp;
    vector<int> re_E[N],E[N<<1];
    #define pb(x) push_back(x)
     
    inline void Tarjan(int nw){
        dfn[nw]=low[nw]=++dfc;stk[++tp]=nw;
        for(int to:re_E[nw])
    	if(!dfn[to]){
    	    Tarjan(to);
    	    low[nw]=min(low[nw],low[to]);
    	    if(low[to]==dfn[nw]){
    		++cnt;
    		for(int x=0;x^to;--tp){
    		    x=stk[tp];
    		    E[x].pb(cnt),E[cnt].pb(x);
    		}
    		E[nw].pb(cnt),E[cnt].pb(nw);
    	    }
    	}
    	else low[nw]=min(low[nw],dfn[to]);
    }
     
    namespace TCP{
        const int _=2e5+10;
        int son[_],siz[_],fa[_],dep[_],tp[_],rol[_];
        multiset<int> W[_>>1];
        struct Segment_tree{
    #define ls(p) p<<1
    #define rs(p) p<<1|1
    	int tr[_<<2];
    	inline void update(int p){tr[p]=min(tr[ls(p)],tr[rs(p)]);return;}
    	inline void Build(int p,int l,int r){
    	    if(l==r){tr[p]=w[rol[l]];return;}
    	    int mid=(l+r)>>1;
    	    Build(ls(p),l,mid),Build(rs(p),mid+1,r);
    	    update(p);
    	}
    	inline void Modify(int p,int l,int r,int pos,int val){
    	    if(l==r){tr[p]=val;return;}
    	    int mid=(l+r)>>1;
    	    if(mid>=pos)Modify(ls(p),l,mid,pos,val);
    	    else Modify(rs(p),mid+1,r,pos,val);
    	    update(p);
    	}
    	inline int Query(int p,int l,int r,int L,int R){
    	    if(L<=l&&r<=R)return tr[p];
    	    int mid=(l+r)>>1,ans=2e9;
    	    if(mid>=L)ans=min(ans,Query(ls(p),l,mid,L,R));
    	    if(mid<R)ans=min(ans,Query(rs(p),mid+1,r,L,R));
    	    return ans;
    	}
        }T;
     
        inline void Dfs_o(int nw,int f=0){
    	siz[nw]=1;dep[nw]=dep[fa[nw]]+1;
    	for(int to:E[nw])
    	    if(to^f){
    		fa[to]=nw;Dfs_o(to,nw);siz[nw]+=siz[to];
    		if(siz[to]>siz[son[nw]])son[nw]=to;
    		if(nw>n)W[nw-n].insert(w[to]);
    	    }
        }
        inline void Dfs_t(int nw){
    	dfn[nw]=++dfc;rol[dfc]=nw;
    	if(!tp[nw])tp[nw]=nw;
    	if(son[nw]){tp[son[nw]]=tp[nw];Dfs_t(son[nw]);}
    	for(int to:E[nw])
    	    if(to^fa[nw]&&to^son[nw])
    		Dfs_t(to);
        }
        inline int lca(int x,int y){
    	int ans=0x7fffffff;
    	while(tp[x]^tp[y]){
    	    if(dep[tp[x]]>=dep[tp[y]])ans=min(ans,T.Query(1,1,dfc,dfn[tp[x]],dfn[x])),x=fa[tp[x]];
    	    else ans=min(ans,T.Query(1,1,dfc,dfn[tp[y]],dfn[y])),y=fa[tp[y]];
    	}
    	if(dep[x]>dep[y])swap(x,y);
    	ans=min(ans,T.Query(1,1,dfc,dfn[x],dfn[y]));
    	if(x>n)ans=min(ans,w[fa[x]]);
    	return ans;
        }
    }using namespace TCP;
     
    int main(){
        n=cnt=read(),m=read(),q=read();
        for(int i=1;i<=n;++i)w[i]=read();
        for(int i=1,u,v;i<=m;++i)u=read(),v=read(),re_E[u].pb(v),re_E[v].pb(u);
        Tarjan(1);memset(dfn,0,sizeof(dfn));dfc=0;
        Dfs_o(1),Dfs_t(1);
        for(int i=n+1;i<=dfc;++i)w[i]=(*W[i-n].begin());
        T.Build(1,1,dfc);
        while(q--){
    	char ch=getchar();
    	switch(ch){
    	case 'C':{
    	    int x=read();
    	    if(x^1){
    		W[fa[x]-n].erase(W[fa[x]-n].find(w[x]));
    		W[fa[x]-n].insert(w[x]=read());
    		T.Modify(1,1,dfc,dfn[fa[x]],(*W[fa[x]-n].begin()));
    	    }
    	    else w[x]=read();
    	    T.Modify(1,1,dfc,dfn[x],w[x]);
    	    break;
    	}
    	case 'A':{
    	    int x=read(),y=read();
    	    printf("%d
    ",TCP::lca(x,y));
    	    break;
    	}
    	}
        }
        return 0;
    }
    
    
  • 相关阅读:
    js 防止页面后退的方法
    asp.net 设置网页过期
    C#子类调用基类构造备忘
    asp.net 自定义控件 嵌入资源文件 备忘
    CSS实现高度和宽度自适应
    C# 更新SQL Server数据库备注信息从另一数据库
    asp.net mvc4 学习笔记一(基本原理)
    CommittableTransaction和TransactionScope
    Delphi7 错误: Access violation at address ****** in module 'ntdll.dll'. Read of address ******.
    Delphi XE10 IdFtp 错误:No FTP list parsers have been registered
  • 原文地址:https://www.cnblogs.com/fruitea/p/12080439.html
Copyright © 2011-2022 走看看