zoukankan      html  css  js  c++  java
  • CF487E & UOJ30:Tourists——题解

    http://uoj.ac/problem/30

    http://codeforces.com/problemset/problem/487/E

    https://www.luogu.com.cn/problem/CF487E

    (洛谷链接可以看中文题面)

    (不会set的脑瘫患者在此)

    题不是很难,圆方树先建起来,就不难想到用multiset维护每个方点为周围圆点权值最小值,然后跑一边树链剖分就好了。

    但是每次修改圆点万一它旁边有一大堆方点暴力修改肯定会TLE。

    所以我们只修改它的父亲方点,这样做的代价就是在查询$(x,y)$时如果$lca(x,y)$是方点那么不要忘了把它的父亲权值考虑在内。

    码力下降太严重了

    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    const int M=4e5+5;
    const int INF=1e9; 
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int u[M],v[M],nxt[M];
        int cnt,head[N];
        void init(){
            cnt=0;memset(head,0,sizeof(head));
        }
        void add(int U,int V){
            u[++cnt]=U;v[cnt]=V;nxt[cnt]=head[U];head[U]=cnt;
        }
    }e,g;
    int n,m,T,w[N];
    int dfn[N],low[N],to[N],t,l;
    stack<int>q;
    void tarjan(int u,int f){
        dfn[u]=low[u]=++t;
        for(int i=g.head[u];i;i=g.nxt[i]){
            int v=g.v[i];
            if(!dfn[v]){
                q.push(i);tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]){
                    int num;l++;
                    do{
                        num=q.top();q.pop();
                        int x=g.u[num],y=g.v[num];
                        if(to[x]!=l){
                            to[x]=l;
                            e.add(x,l+n);e.add(l+n,x);
                        }
                        if(to[y]!=l){
                            to[y]=l;
                            e.add(y,l+n);e.add(l+n,y);
                        }
                    }while(num!=i);
                }
            }else if(low[u]>dfn[v]&&f!=v){
                q.push(i);low[u]=dfn[v];
            }
        }
    }
    inline bool is_square(int x){
        return x>n;
    }
    multiset<int>minn[N];
    int tot,fa[N],pos[N],idx[N],size[N],son[N],dep[N],top[N],val[N];
    void dfs1(int u){
        size[u]=1;
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(fa[u]==v)continue;
            fa[v]=u;dep[v]=dep[u]+1;
            if(is_square(u))minn[u].insert(w[v]);
            dfs1(v);size[u]+=size[v];
            if(!son[u]||size[son[u]]<size[v])son[u]=v;
        }
    }
    void dfs2(int u,int anc){
        pos[u]=++tot;idx[tot]=u;top[u]=anc;
        if(!son[u])return;
        dfs2(son[u],anc);
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(v==fa[u]||v==son[u])continue;
            dfs2(v,v);
        }
    }
    inline void init(){
        dep[1]=1;
        dfs1(1);
        dfs2(1,1);
    }
    int tr[N<<2];
    void build(int a,int l,int r){
        if(l==r){
            tr[a]=(is_square(idx[l]))? *minn[idx[l]].begin():w[idx[l]];
            return;
        }
        int mid=(l+r)>>1;
        build(a<<1,l,mid);build(a<<1|1,mid+1,r);
        tr[a]=min(tr[a<<1],tr[a<<1|1]);
    }
    inline int query(int a,int l,int r,int l1,int r1){
        if(r1<l||l1>r)return INF;
        if(l1<=l&&r<=r1)return tr[a];
        int mid=(l+r)>>1;
        return min(query(a<<1,l,mid,l1,r1),query(a<<1|1,mid+1,r,l1,r1));
    }
    inline void modify(int a,int l,int r,int x){
        if(x<l||r<x)return;
        if(l==r){
            tr[a]=(is_square(idx[l]))? *minn[idx[l]].begin():w[idx[l]];
            return;
        }
        int mid=(l+r)>>1;
        modify(a<<1,l,mid,x);modify(a<<1|1,mid+1,r,x);
        tr[a]=min(tr[a<<1],tr[a<<1|1]);
    }
    inline int qry(int x,int y){
        int ans=INF;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans=min(ans,query(1,1,n+l,pos[top[x]],pos[x]));
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        ans=min(ans,query(1,1,n+l,pos[x],pos[y]));
        return is_square(x)?min(ans,query(1,1,n+l,pos[fa[x]],pos[fa[x]])):ans;
    }
    inline void mdy(int x,int y){
        if(fa[x]){
            minn[fa[x]].insert(y);
            minn[fa[x]].erase(minn[fa[x]].find(w[x]));
            modify(1,1,n+l,pos[fa[x]]);
        }
        w[x]=y;
        modify(1,1,n+l,pos[x]);
    }
    int main(){
        n=read(),m=read(),T=read();
        for(int i=1;i<=n;i++)w[i]=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            g.add(u,v);g.add(v,u);
        }
        tarjan(1,0);
        init();build(1,1,n+l);
        for(int i=1;i<=T;i++){
            char c=getchar();
            int x=read(),y=read();
            if(c=='C')mdy(x,y);
            if(c=='A')printf("%d
    ",qry(x,y));
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    MySQL锁之一:锁详解
    eclipse maven plugin 插件 安装 和 配置
    火星坐标系统
    使用Spring MVC统一异常处理实战
    websocket之二:WebSocket编程入门
    spring mvc 异常统一处理方式
    Android面向HTTP协议发送post请求
    用JAX-WS在Tomcat中公布WebService
    css3 -&gt; 多栏布局
    NSLayoutConstraint-代码实现自己主动布局的函数使用方法说明
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12269428.html
Copyright © 2011-2022 走看看