zoukankan      html  css  js  c++  java
  • 洛谷 P4114 Qtree1

    洛谷 P4114 Qtree1

    洛谷传送门

    题目背景

    数据规模和 spoj 上有所不同

    题目描述

    给定一棵 nn 个节点的树,有两种操作:

    • CHANGE i t 把第 ii 条边的边权变成 tt
    • QUERY a b 输出从 aa 到 bb 的路径上最大的边权。当 a=ba=b 时,输出 00

    输入格式

    第一行是一个整数 nn,表示节点个数。
    第二行到第 nn 行每行输入三个整数 u,v,wu,v,w ,分别表示 uu 与 vv 有一条边,边权是 ww
    第 n+1n+1 行开始,一共有不定数量行,每一行先包含一个字符串,分别有以下三种可能:

    • CHANGE 接下来包含两个整数 x, tx,t ,表示一次修改操作。
    • QUERY 接下来包含两个正整数 a, ba,b , 表示一次查询操作。
    • DONE 表示输入结束。

    输出格式

    对于每个 QUERY 操作,输出一行一个数,表示 a,ba,b 的路径上最大的边权。


    题解:

    树剖+边转点。

    练手模板题。

    代码:

    #include<bits/stdc++.h>
    #define N 100003
    #define ls(u) (u<<1)
    #define rs(u) (u<<1|1)
    #define mid ((l+r)>>1)
    using namespace std;
    const int inf=1e9;
    struct edge{
        int u,v,w;
        edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
    };
    int wl[N],son[N],size[N],top[N],b[N],id[N];
    int a[N<<2],tag[N<<2],depth[N],fa[N],mx[N<<2];
    edge e[N];
    int n,m,r,cnt;
    vector<edge> adj[N];
    inline void read(int &x){
        x = 0;
        char c = getchar();
        while(!isdigit(c)) c = getchar();
        while(isdigit(c)){
            x = (x<<3)+(x<<1)+c-'0';
            c = getchar();
        }
    }
    void print(int x){
        if(x>9) print(x/10);
        putchar(x%10+'0');
    }
    inline int max(int a,int b){
        return a>b?a:b;
    }
    inline void push_up(int u){
        a[u] = a[ls(u)]+a[rs(u)];
        mx[u] = max(mx[ls(u)],mx[rs(u)]);
    }
    void build(int u,int l,int r){
        if(l==r){
            a[u] = mx[u] = wl[l];
            return;
        }
        build(ls(u),l,mid);
        build(rs(u),mid+1,r);
        push_up(u);
    }
    void update(int u,int l,int r,int q,int k){
        if(l==r){
            a[u] = mx[u] = k;
            return;
        }
        if(q<=mid) update(ls(u),l,mid,q,k);
        else update(rs(u),mid+1,r,q,k);
        push_up(u);
    }
    int qaq(int nl,int nr,int l,int r,int u){
        int res = -inf;
        if(nl<=l&&r<=nr) return mx[u];
        if(nl<=mid) res = max(res,qaq(nl,nr,l,mid,ls(u)));
        if(nr>mid) res = max(res,qaq(nl,nr,mid+1,r,rs(u)));
        push_up(u);
        return res;
    }
    inline int qmax(int l,int r){
        return qaq(l,r,1,n,1);
    }
    void dfs1(int u,int f){
        fa[u] = f;
        depth[u] = depth[f]+1;
        size[u] = 1;
        int v,t = -1,l = adj[u].size();
        for(int i=0;i<l;i++){
            v = adj[u][i].v;
            if(v==f){
                b[u] = adj[u][i].w;
                continue;
            }
            dfs1(v,u);
            size[u] += size[v];
            if(size[v]>t){
                t = size[v];
                son[u] = v;
            }
        }
    }
    void dfs2(int u,int f)
    {
        top[u] = f;
        id[u] = ++cnt;
        wl[cnt] = b[u];
        if(son[u]==0) return;
        dfs2(son[u],f);
        int v,l = adj[u].size();
        for(int i=0;i<l;i++){
            v = adj[u][i].v;
            if(v==fa[u]||v==son[u]) continue;
            dfs2(v,v);
        }
    }
    int q_chain(int u,int v)
    {
        int res = -inf;
        while(top[u]!=top[v]){
            if(depth[top[u]]<depth[top[v]])
                swap(u,v);
            res = max(res,qmax(id[top[u]],id[u]));
            u = fa[top[u]];
        }
        if(depth[u]>depth[v]) swap(u,v);
        res = max(res,qmax(id[u]+1,id[v]));
        return res;
    }
    int main()
    {
        int u,v,w,q;
        string str;
        read(n);
        for(int i=1;i<n;i++)
    	{
            read(u),read(v),read(w);
            adj[u].push_back(edge(u,v,w));
            adj[v].push_back(edge(v,u,w));
            e[i] = edge(u,v,w);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        string op;
        while(1)
    	{
            op = "";
            char c = getchar();
            while(c<'A'||c>'Z') 
    			c = getchar();
            while(c>='A'&&c<='Z')
    		{
                op.push_back(c);
                c = getchar();
            }
            if(op=="DONE") 
    			break;
            read(u),read(v);
            if(op=="QUERY")
    		{
                if(u==v) 
    				putchar('0');
                else 
    				print(q_chain(u,v));
                putchar('
    ');
            }
    		else
    		{
                if(depth[e[u].u]>depth[e[u].v]) 
    				u = e[u].u;
                else 
    				u = e[u].v;
                update(1,1,n,id[u],v);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    微信小程序-开发入门(一)
    Vue入门
    美化input type=range标签滑动样式(带渐变效果)
    全新的css网站布局--Grid布局
    移动端布局与样式上的坑
    swiper 下拉刷新混乱
    子元素scroll父元素容器不跟随滚动JS实现
    解决前端页面闪烁问题(转载)
    VUE 与其他常见前端框架对比
    移动端表层div滑动,导致底层body滑动(touchmove的阻止)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13851297.html
Copyright © 2011-2022 走看看