zoukankan      html  css  js  c++  java
  • HYSBZ 1036 树的统计Count

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036

    题意:

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

    我们将以下面的形式来要求你对这棵树完成一些操作:

    I. CHANGE u t : 把结点u的权值改为t

    II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

    III. QSUM u v: 询问从点u到点v的路径上的节点的权值和

    注意:从点u到点v的路径上的节点包括u和v本身

    思路:

    权值在点上的树链剖分+线段树单点更新+线段树成段询问。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <string>
      4 #include <cstdio>
      5 #include <vector>
      6 using namespace std;
      7 int n, q;
      8 #define maxn 30010
      9 #define lson l, m, rt<<1
     10 #define rson m+1, r, rt<<1|1
     11 int siz[maxn], top[maxn], fa[maxn], son[maxn], dep[maxn];
     12 int w[maxn], fw[maxn];
     13 int A[maxn];
     14 vector <int> mp[maxn];
     15 int pos;
     16 int sum[maxn<<2], mmax[maxn<<2];
     17 int col[maxn<<2];
     18 void PushUp(int rt)
     19 {
     20     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     21     mmax[rt] = max(mmax[rt<<1], mmax[rt<<1|1]);
     22 }
     23 void build(int l, int r, int rt)
     24 {
     25     mmax[rt] = -0x3f3f3f3f;
     26     sum[rt] = 0;
     27     if(l == r)
     28     {
     29         mmax[rt] = A[fw[l]];
     30         sum[rt] = A[fw[l]];
     31         return;
     32     }
     33     int m = (l+r)>>1;
     34     build(lson);
     35     build(rson);
     36     PushUp(rt);
     37 }
     38 void update(int p, int val, int l, int r, int rt)
     39 {
     40     if(l == r)
     41     {
     42         sum[rt] = val; mmax[rt] = val; col[rt] = 0;
     43         return;
     44     }
     45     int m = (l+r)>>1;
     46     if(p <= m) update(p, val, lson);
     47     else update(p, val, rson);
     48     PushUp(rt);
     49 }
     50 int query_max(int L, int R, int l, int r, int rt)
     51 {
     52     if(L <= l && R >= r)
     53     {
     54         return mmax[rt];
     55     }
     56     int m = (l+r)>>1;
     57     int ret = -0x3f3f3f3f;
     58     if(L <= m) ret = max(ret, query_max(L, R, lson));
     59     if(R > m) ret = max(ret, query_max(L, R, rson));
     60     return ret;
     61 }
     62 int query_sum(int L, int R, int l, int r, int rt)
     63 {
     64     if(L <= l && R >= r)
     65     {
     66         return sum[rt];
     67     }
     68     int m = (l+r)>>1;
     69     int ret = 0;
     70     if(L <= m) ret += query_sum(L, R, lson);
     71     if(R > m) ret += query_sum(L, R, rson);
     72     return ret;
     73 }
     74 int dfs1(int u, int pre, int deep)
     75 {
     76     siz[u] = 1; dep[u] = deep; fa[u] = pre;
     77     int mmax = 0;
     78     for(int i = 0; i < mp[u].size(); i++)
     79     {
     80         if(mp[u][i] != pre)
     81         {
     82             int temp = dfs1(mp[u][i], u, deep+1);
     83             siz[u] += temp;
     84             if(son[u] == -1 || temp >= mmax) 
     85             {
     86                 son[u] = mp[u][i];
     87                 mmax = temp;
     88             }
     89         }
     90     }
     91     return siz[u];
     92 }
     93 void dfs2(int u, int val)
     94 {
     95     top[u] = val;
     96     if(son[u] != -1)
     97     {
     98         w[u] = ++pos;
     99         fw[w[u]] = u;
    100         dfs2(son[u], val);
    101     }
    102     else if(son[u] == -1)
    103     {
    104         w[u] = ++pos;
    105         fw[w[u]] = u;
    106         return;
    107     }
    108     for(int i = 0; i < mp[u].size(); i++)
    109     {        
    110         if(mp[u][i] != son[u] && mp[u][i] != fa[u]) dfs2(mp[u][i], mp[u][i]);
    111     }
    112 }
    113 int find_sum(int u, int v)
    114 {
    115     int f1 = top[u], f2 = top[v];
    116     int temp = 0;
    117     while(f1 != f2)
    118     {
    119         if(dep[f1] < dep[f2])
    120         {
    121             swap(f1, f2); 
    122             swap(u, v);
    123         }
    124         temp += query_sum(w[f1], w[u], 1, pos, 1);
    125         u = fa[f1]; f1 = top[u];
    126     }
    127     if(dep[u] > dep[v]) swap(u, v);
    128     temp += query_sum(w[u], w[v], 1, pos, 1);
    129     return temp;
    130 }
    131 int find_max(int u, int v)
    132 {
    133     int f1 = top[u], f2 = top[v];
    134     int temp = -0x3f3f3f3f;
    135     while(f1 != f2)
    136     {
    137         if(dep[f1] < dep[f2])
    138         {
    139             swap(f1, f2);
    140             swap(u, v);
    141         }
    142         temp = max(temp, query_max(w[f1], w[u], 1, pos, 1));
    143         u = fa[f1]; f1 = top[u];
    144     }
    145     if(dep[u] > dep[v]) swap(u, v);
    146     temp = max(temp, query_max(w[u], w[v], 1, pos, 1));
    147     return temp;
    148 }
    149 int main() 
    150 {
    151   //  freopen("in.txt", "r", stdin);
    152    // freopen("out.txt", "w", stdout);
    153     while(~scanf("%d", &n))
    154     {
    155         for(int i = 1; i <= n; i++) mp[i].clear(); 
    156         pos = 0;
    157         memset(son, -1, sizeof(son));
    158         for(int i = 1; i <= n-1; i++)
    159         {
    160             int a, b; scanf("%d%d", &a, &b);
    161             mp[a].push_back(b);
    162             mp[b].push_back(a);
    163         }
    164         for(int i = 1; i <= n; i++) scanf("%d", &A[i]);
    165         dfs1(1, -1, 1);
    166         dfs2(1, 1);
    167         build(1, pos, 1);
    168         
    169         scanf("%d", &q);
    170         char op[10];
    171         while(q--)
    172         {
    173             scanf("%s", op); int u, v; 
    174             scanf("%d%d", &u, &v);
    175             if(op[0] == 'C') update(w[u], v, 1, pos, 1);
    176             else if(op[1] == 'M') printf("%d
    ", find_max(u, v));
    177             else if(op[1] == 'S') printf("%d
    ", find_sum(u, v));
    178             
    179         }
    180         
    181     }
    182     return 0;
    183 }
  • 相关阅读:
    Jmeter常用脚本开发之JDBC请求
    Jmeter常用脚本开发之Java请求
    Jmeter常用脚本开发之FTP请求
    Jmeter常用脚本开发之Debug Sampler
    Jmeter常用脚本开发之Beanshell Sampler
    Jenkins构建.net项目
    Charles基本使用
    [daily] emacs显示file name buffer的全路径
    [dev] 刷HHKP的一般流程及常见错误(多图慎点)
    [dev][go] 入门Golang都需要了解什么
  • 原文地址:https://www.cnblogs.com/titicia/p/4902432.html
Copyright © 2011-2022 走看看