zoukankan      html  css  js  c++  java
  • poj 3237 Tree

    题目链接:http://poj.org/problem?id=3237

    题意:

    给出N个节点的树,每条边有权值。有3种操作:

    CHANGE i v 改变第i条边的权值,变成v

    NEGATE a b a到b的路径上的每条边的权值取相反数

    QUERY a b 找出a到b路径上权值最大的边输出

    思路:

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

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <vector>
      5 #include <algorithm>
      6 using namespace std;
      7 #define lson l, m, rt<<1
      8 #define rson m+1, r, rt<<1|1
      9 #define maxn 10010
     10 struct Node
     11 {
     12     int to, val;
     13     Node(int t, int v)
     14     {
     15         to = t; val = v;
     16     }
     17     Node(){}
     18 };
     19 struct Edge
     20 {
     21     int from, to, val;
     22 }e[maxn];
     23 vector <Node> mp[maxn];
     24 int N;
     25 int siz[maxn]; //表示以v为根的子树的节点数
     26 int dep[maxn]; //表示v的深度(根深度为1)
     27 int top[maxn]; //表示v所在的重链的顶端节点
     28 int fa[maxn];  //表示v的父亲
     29 int son[maxn]; //表示与v在同一重链上的v的儿子节点(姑且称为重儿子)
     30 int w[maxn];   //表示v与其父亲节点的连边(姑且称为v的父边)在线段树中的位置
     31 int pos;
     32 int mmax[maxn<<2], mmin[maxn<<2],col[maxn<<2];
     33 void PushUp(int rt)
     34 {
     35     mmax[rt] = max(mmax[rt<<1], mmax[rt<<1|1]);
     36     mmin[rt] = min(mmin[rt<<1], mmin[rt<<1|1]);
     37 }
     38 void PushDown(int rt)
     39 {
     40     if(col[rt])
     41     {
     42         col[rt<<1] ^= 1; col[rt<<1|1] ^= 1;
     43         int tempmax, tempmin;
     44         tempmax = mmax[rt<<1]; tempmin = mmin[rt<<1];
     45         mmax[rt<<1] = -tempmin; mmin[rt<<1] = -tempmax;
     46         tempmax = mmax[rt<<1|1]; tempmin = mmin[rt<<1|1];
     47         mmax[rt<<1|1] = -tempmin; mmin[rt<<1|1] = -tempmax;
     48         col[rt] = 0;
     49     }
     50 }
     51 void build(int l, int r, int rt)
     52 {
     53     col[rt] = 0;
     54     mmax[rt] = -0x3f3f3f3f; 
     55     mmin[rt] = 0x3f3f3f3f; 
     56     
     57     if(l == r) return;
     58     int m = (l+r)>>1;
     59     build(lson);
     60     build(rson);
     61     PushUp(rt);
     62 }
     63 void update(int p, int val, int l, int r, int rt)
     64 {
     65     if(l == r)
     66     {
     67         col[rt] = 0;
     68         mmax[rt] = val; mmin[rt] = val;
     69         return;
     70     }
     71     PushDown(rt);
     72     int m = (l+r)>>1;
     73     if(p <= m) update(p, val, lson);
     74     else update(p, val, rson);
     75     PushUp(rt);
     76 }
     77 void update2(int L, int R, int l, int r, int rt)
     78 {
     79     if(L <= l && R >= r)
     80     {
     81         col[rt] ^= 1;
     82         int tempmax = mmax[rt], tempmin = mmin[rt];
     83         mmax[rt] = -tempmin; mmin[rt] = -tempmax;
     84         return;
     85     }
     86     PushDown(rt);
     87     int m = (l+r)>>1;
     88     if(L <= m) update2(L, R, lson);
     89     if(R > m) update2(L, R, rson);
     90     PushUp(rt);
     91 }
     92 int query(int L, int R, int l, int r, int rt)
     93 {
     94     if(L <= l && R >= r)
     95     {
     96         return mmax[rt];
     97     }
     98     PushDown(rt);
     99     int ret = -0x3f3f3f3f;
    100     int m = (l+r)>>1;
    101     if(L <= m) ret = max(ret, query(L, R, lson));
    102     if(R > m) ret = max(ret, query(L, R, rson));
    103     return ret;
    104 }
    105 int dfs1(int u, int pre, int deep)
    106 {
    107     siz[u] = 1; dep[u] = deep; fa[u] = pre;
    108     int mmax = 0;
    109     for(int i = 0; i < mp[u].size(); i++)
    110     {
    111         if(mp[u][i].to != pre)
    112         {
    113             int temp = dfs1(mp[u][i].to, u, deep+1);
    114             siz[u] += temp;
    115             if(son[u] == -1 || temp >= mmax) son[u] = mp[u][i].to;
    116         }
    117     }
    118     return siz[u];
    119 }
    120 void dfs2(int u, int val)
    121 {
    122     top[u] = val;
    123     if(son[u] != -1)  //如果不是叶子节点,线段树中,v的重边应当在v的父边的后面
    124     {
    125         w[u] = pos++;
    126         dfs2(son[u], val);
    127     }
    128     else if(son[u] == -1)
    129     {
    130         w[u] = pos++;
    131         return;
    132     }
    133     for(int i = 0; i < mp[u].size(); i++)
    134     {
    135         if(mp[u][i].to != son[u] && mp[u][i].to != fa[u]) dfs2(mp[u][i].to, mp[u][i].to);//对于v的各个轻儿子u,top[u] = u
    136     }
    137 }
    138 int find(int u, int v)
    139 {
    140     int f1 = top[u], f2 = top[v];
    141     int temp = -0x3f3f3f3f;
    142     while(f1 != f2)
    143     {
    144         if(dep[f1] < dep[f2])  //设dep[f1] >= dep[f2]
    145         {
    146             swap(f1, f2);
    147             swap(u, v);
    148         }
    149         temp = max(temp, query(w[f1],w[u], 1, pos-1, 1));
    150         u = fa[f1]; f1 = top[u];
    151     }
    152     if(u == v) return temp;
    153     if(dep[u] > dep[v]) swap(u, v);
    154     return max(temp, query(w[son[u]], w[v], 1, pos-1, 1));
    155 }
    156 void Negate(int u, int v)
    157 {
    158    int f1 = top[u], f2 = top[v];
    159    while(f1 != f2)
    160    {
    161        if(dep[f1] < dep[f2])
    162        {
    163            swap(f1, f2);
    164            swap(u, v);
    165        }
    166        update2(w[f1], w[u], 1, pos-1, 1);
    167        u = fa[f1]; f1 = top[u];
    168    } 
    169    if(u == v) return;
    170    if(dep[u] > dep[v]) swap(u, v);
    171    update2(w[son[u]], w[v], 1, pos-1, 1);
    172 }
    173 int main() 
    174 {
    175    // freopen("in.txt", "r", stdin);
    176     //freopen("out.txt", "w", stdout);
    177     int T; scanf("%d", &T);
    178     while(T--)
    179     {
    180         scanf("%d", &N);
    181         pos = 0; memset(son, -1, sizeof(son));
    182         for(int i = 1; i <= N; i++) mp[i].clear();
    183         for(int i = 1; i <= N-1; i++)
    184         {
    185             scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].val);
    186             mp[e[i].from].push_back(Node(e[i].to, e[i].val));
    187             mp[e[i].to].push_back(Node(e[i].from, e[i].val));
    188         }
    189         dfs1(1, -1, 1);
    190         dfs2(1, 1);
    191         build(1, pos-1, 1);
    192         for(int i = 1; i <= N-1; i++)
    193         {
    194             if(dep[e[i].from] > dep[e[i].to])
    195             {
    196                 swap(e[i].from, e[i].to);
    197             }
    198             update(w[e[i].to], e[i].val, 1, pos-1, 1);
    199         }
    200         char op[15];
    201         while(scanf("%s", op))
    202         {
    203             if(op[0] == 'D') break;
    204             int a, b; scanf("%d%d", &a, &b);
    205             if(op[0] == 'Q') printf("%d
    ", find(a, b));
    206             else if(op[0] == 'C') update(w[e[a].to], b, 1, pos-1, 1);
    207             else if(op[0] == 'N') Negate(a, b);
    208 
    209         }
    210     }
    211 
    212     return 0;
    213 }
  • 相关阅读:
    js 手机端触发事事件、javascript手机端/移动端触发事件
    行高引起的行内块级元素间距
    js实现复制功能
    encodeURI、encodeURIComponent、decodeURI、decodeURIComponent的区别
    CSS动画总结效果
    CSS属性之word-break:break-all强制性换行
    在handlebars.js {{#if}}条件下的逻辑运算符解决方案
    js模版引擎handlebars.js实用教程——由于if功力不足引出的Helper
    垂直方向兼容显示的内容多少的情况样式Flex布局
    实现div里的img图片水平垂直居中
  • 原文地址:https://www.cnblogs.com/titicia/p/4902415.html
Copyright © 2011-2022 走看看