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

    题目描述

    给定一棵(n)个节点的树,有两个操作:

    (CHANGE) (i) (t_i) 把第(i)条边的边权变成(t_i)

    (QUERY) (a) (b) 输出从(a)(b)的路径中最大的边权,当(a=b)的时候,输出(0)

    输入输出格式

    输入格式:

    第一行输入一个(n),表示节点个数

    第二行到第(n)行每行输入三个数,(u_i)(v_i)(w_i),分别表示 (u_i)(v_i)有一条边,边权是(w_i)

    (n+1)行开始,一共有不定数量行,每一行分别有以下三种可能

    (CHANGE)(QUERY)同题意所述

    (DONE)表示输入结束

    输出格式:

    对于每个(QUERY)操作,输出一个数,表示(a) (b)之间边权最大值

    输入输出样例

    输入样例#1:

    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    

    输出样例#1:

    1
    3
    

    说明

    数据保证:

    (1 leq n leq 10^5)

    操作次数 (leq 3*10^5)

    (wi)(ti) (leq 2^{31}−1)

    思路:读完题目之后……诶,这不是树链剖分裸题么??!!

    然后……代码写到一半忽然发现是边权……而普通的树链剖分是点权,如果是点权的话,那这道题就是一个裸题了吧。然后,我们可以发现,一个点连向它父亲的边有且只有一个,即一个点只有一个父亲,那么我们就可以用它的点权来代替它与它父亲之间的那条边的边权,然后,就成了一个裸题了……

    还有要注意的一点就是,区间查询的时候不要把LCA算上,因为它的点权代表它与它父亲的边权,不在查询的路径上。

    自己整理的题解

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 100007
    #define ll long long
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    int n,head[maxn],d[maxn],size[maxn],son[maxn],a[maxn],lazy[maxn<<2];
    int p[maxn],id[maxn],top[maxn],num,cnt,fa[maxn],maxx[maxn<<2];
    char s[10];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int v,w,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v, int w) {
      e[++num].v=v;
      e[num].w=w;
      e[num].nxt=head[u];
      head[u]=num;
    }
    inline void pushup(int rt) {
      maxx[rt]=max(maxx[ls],maxx[rs]);
    }
    inline void pushdown(int rt) {
      if(lazy[rt]>=0) {
        maxx[ls]=maxx[rs]=lazy[ls]=lazy[rs]=lazy[rt];
        lazy[rt]=-1;
      }
    }
    void build(int rt, int l, int r) {
      lazy[rt]=-1;
      if(l==r) {
        maxx[rt]=a[l];
        return;
      }
      int mid=(l+r)>>1;
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(rt);
    }
    void modify(int rt, int l, int r, int L, int R, int val) {
      if(L>r||R<l) return;
      if(L<=l&&r<=R) {
        maxx[rt]=lazy[rt]=val;
        return;
      }
      pushdown(rt);
      int mid=(l+r)>>1;
      modify(ls,l,mid,L,R,val),modify(rs,mid+1,r,L,R,val);
      pushup(rt);
    }
    int cmax(int rt, int l, int r, int L, int R) {
      if(L<=l&&r<=R) return maxx[rt];
      int ans=0;
      int mid=(l+r)>>1;
      pushdown(rt);
      if(L<=mid) ans=max(ans,cmax(ls,l,mid,L,R));
      if(R>mid) ans=max(ans,cmax(rs,mid+1,r,L,R));
      return ans;
    }
    void dfs1(int u, int f) {
      size[u]=1;
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=f) {
          d[v]=d[u]+1;
          fa[v]=u;
          p[v]=e[i].w;
          dfs1(v,u);
          size[u]+=size[v];
          if(size[v]>size[son[u]]) son[u]=v;
        }
      }
    }
    void dfs2(int u, int t) {
      id[u]=++cnt;
      top[u]=t;
      a[cnt]=p[u];
      if(son[u]) dfs2(son[u],t);
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
      }
    }
    int query(int x, int y) {
      int ans=0,fx=top[x],fy=top[y];
      while(fx!=fy) {
        if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
        ans=max(ans,cmax(1,1,n,id[fx],id[x]));
        x=fa[fx],fx=top[x];
      }
      if(id[x]>id[y]) swap(x,y);
      ans=max(ans,cmax(1,1,n,id[x]+1,id[y]));
      return ans;
    }
    int main() {
      n=qread();
      for(int i=1,u,v,w;i<n;++i) {
        u=qread(),v=qread(),w=qread();
        ct(u,v,w);ct(v,u,w);
      }
      dfs1(1,0),dfs2(1,1);build(1,1,n);
      while(1) {
        scanf("%s",s);
        if(s[0]=='D') break;
        int x=qread(),y=qread();
        if(s[0]=='Q') {
          if(x==y) printf("0
    ");
          else printf("%d
    ",query(x,y));
    	}
    	if(s[0]=='C') {
    	  x=d[e[x*2-1].v]<d[e[x<<1].v]?e[x<<1].v:e[x*2-1].v;
          modify(1,1,n,id[x],id[x],y);
    	}
      }
      return 0;
    }
    
  • 相关阅读:
    数码摄影入门之十 数码相片后期处理
    Easy CHM 2.10
    LeapFTP 3.0.0.43 汉化版(附带LeapFTP 3.0注册码)
    使用“淘宝助理”的常见错误
    “互联网浏览器”控件与webBrowser控件的区别
    易语言源代码毁来者来了!!
    易语言正则表达式的多行匹配替换
    Explorer.exe鲜为人知的参数
    原始套接字概述
    网络技术数据封装
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201468.html
Copyright © 2011-2022 走看看