zoukankan      html  css  js  c++  java
  • BZOJ 2157: 旅游

    2157: 旅游

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 1347  Solved: 619
    [Submit][Status][Discuss]

    Description

    Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。

    Input

    输入的第一行包含一个整数N,表示T 城中的景点个数。景点编号为 0...N − 1。接下来N − 1 行,每行三个整数u、v 和w,表示有一条u 到v,使 Ray 愉悦度增加w 的桥。桥的编号为1...N − 1。|w| <= 1000。输入的第N + 1 行包含一个整数M,表示Ray 的操作数目。接下来有M 行,每行描述了一个操作,操作有如下五种形式: C i w,表示Ray 对于经过第i 座桥的愉悦度变成了w。 N u v,表示Ray 对于经过景点u 到v 的路径上的每一座桥的愉悦度都变成原来的相反数。 SUM u v,表示询问从景点u 到v 所获得的总愉悦度。 MAX u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最大愉悦度。 MIN u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最小愉悦度。测试数据保证,任意时刻,Ray 对于经过每一座桥的愉悦度的绝对值小于等于1000。

    Output

    对于每一个询问(操作S、MAX 和MIN),输出答案。

    Sample Input

    3
    0 1 1
    1 2 2
    8
    SUM 0 2
    MAX 0 2
    N 0 1
    SUM 0 2
    MIN 0 2
    C 1 3
    SUM 0 2
    MAX 0 2

    Sample Output

    3
    2
    1
    -1
    5
    3

    HINT

    一共有10 个数据,对于第i (1 <= i <= 10) 个数据, N = M = i * 2000。

    Source

     
    [Submit][Status][Discuss]

    Link-Cut-Tree 模板题

    维护子树(路径)最值、权值和

      1 #include <cstdio>
      2 
      3 template <class T>
      4 inline T swap(T &a, T &b)
      5 {
      6     T c;
      7     c = a;
      8     a = b;
      9     b = c;
     10 }
     11 
     12 template <class T>
     13 inline T max(const T &a, const T &b)
     14 {
     15     return a > b ? a : b;
     16 }
     17 
     18 template <class T>
     19 inline T min(const T &a, const T &b)
     20 {
     21     return a < b ? a : b;
     22 }
     23 
     24 const int mxn = 50005;
     25 const int inf = 1e9 + 9;
     26 
     27 int n, m, val[mxn];
     28 
     29 struct node
     30 {
     31     int sum;
     32     int maxi;
     33     int mini;
     34     bool neg;
     35     bool rev;
     36     node *son[2];
     37     node *father;
     38 }tree[mxn];
     39 
     40 inline bool isRoot(node *t)
     41 {
     42     node *&f = t->father;
     43     
     44     if (f == NULL)return true;
     45     
     46     if (f->son[0] == t)return false;
     47     if (f->son[1] == t)return false;
     48     
     49     return true;
     50 }
     51 
     52 inline void addNeg(node *t)
     53 {
     54     t->neg ^= true;
     55     
     56     swap(t->maxi, t->mini);
     57     
     58     t->sum = -t->sum;
     59     t->maxi = -t->maxi;
     60     t->mini = -t->mini;
     61     
     62     if (t - tree >= n)
     63     {    // edge
     64         int id = t - tree - n;
     65         
     66         val[id] = -val[id];
     67     }
     68 }
     69 
     70 inline void pushNeg(node *t)
     71 {
     72     if (t->neg)
     73     {
     74         t->neg = false;
     75         
     76         if (t->son[0] != NULL)addNeg(t->son[0]);
     77         if (t->son[1] != NULL)addNeg(t->son[1]);
     78     }
     79 }
     80 
     81 inline void addRev(node *t)
     82 {
     83     t->rev ^= true;
     84     
     85     swap(t->son[0], t->son[1]);
     86 }
     87 
     88 inline void pushRev(node *t)
     89 {
     90     if (t->rev)
     91     {
     92         t->rev = false;
     93         
     94         if (t->son[0] != NULL)addRev(t->son[0]);
     95         if (t->son[1] != NULL)addRev(t->son[1]);
     96     }
     97 }
     98 
     99 inline void update(node *t)
    100 {
    101     if (t - tree < n)
    102     {    // point
    103         t->sum = 0;
    104         t->maxi = -inf;
    105         t->mini = +inf;
    106     }
    107     else
    108     {    // edge
    109         int id = t - tree - n;
    110         
    111         t->sum = val[id];
    112         t->maxi = val[id];
    113         t->mini = val[id];
    114     }
    115     
    116     if (t->son[0] != NULL)
    117     {
    118         t->sum += t->son[0]->sum;
    119         t->maxi = max(t->maxi, t->son[0]->maxi);
    120         t->mini = min(t->mini, t->son[0]->mini);
    121     }
    122     if (t->son[1] != NULL)
    123     {
    124         t->sum += t->son[1]->sum;
    125         t->maxi = max(t->maxi, t->son[1]->maxi);
    126         t->mini = min(t->mini, t->son[1]->mini);
    127     }
    128 }
    129 
    130 inline void connect(node *t, node *f, bool k)
    131 {
    132     if (t != NULL)t->father = f;
    133     if (f != NULL)f->son[k] = t;
    134 }
    135 
    136 inline void rotate(node *t)
    137 {
    138     node *f = t->father;
    139     node *g = f->father;
    140     
    141     bool s = f->son[1] == t;
    142     
    143     connect(t->son[!s], f, s);
    144     connect(f, t, !s);
    145     
    146     t->father = g;
    147     if (g && g->son[0] == f)g->son[0] = t;
    148     if (g && g->son[1] == f)g->son[1] = t;
    149     
    150     update(f);
    151     update(t);
    152 }
    153 
    154 inline void pushdown(node *t)
    155 {
    156     pushNeg(t);
    157     pushRev(t);
    158 }
    159 
    160 inline void pushDown(node *t)
    161 {
    162     static node *stk[mxn];
    163     
    164     int top = 0;
    165     
    166     stk[++top] = t;
    167     
    168     while (!isRoot(t))
    169         stk[++top] = t = t->father;
    170     
    171     while (top)pushdown(stk[top--]);
    172 }
    173 
    174 inline void splay(node *t)
    175 {
    176     pushDown(t);
    177     
    178     while (!isRoot(t))
    179     {
    180         node *f = t->father;
    181         node *g = f->father;
    182         
    183         if (isRoot(f))
    184             rotate(t);
    185         else
    186         {
    187             bool a = f && f->son[1] == t;
    188             bool b = g && g->son[1] == f;
    189             
    190             if (a == b)
    191                 rotate(f), rotate(t);
    192             else
    193                 rotate(t), rotate(t);
    194         }
    195     }
    196 }
    197 
    198 inline void access(node *t)
    199 {
    200     node *q = t;
    201     node *p = NULL;
    202     
    203     while (t != NULL)
    204     {
    205         splay(t);
    206         t->son[1] = p, update(t);
    207         p = t, t = t->father;
    208     }
    209     
    210     splay(q);
    211 }
    212 
    213 inline void makeRoot(node *t)
    214 {
    215     access(t), addRev(t);
    216 }
    217 
    218 inline void link(node *t, node *f)
    219 {
    220     makeRoot(t), t->father = f;
    221 }
    222 
    223 signed main(void)
    224 {
    225     scanf("%d", &n);
    226     
    227     for (int i = 1; i <= n; ++i)
    228         update(tree + i);
    229     for (int i = 1, x, y, w; i < n; ++i)
    230     {
    231         scanf("%d%d%d", &x, &y, &w);
    232         val[i] = w, update(tree + i + n);
    233         link(tree + x, tree + i + n);
    234         link(tree + y, tree + i + n);
    235     }
    236     
    237     scanf("%d", &m);
    238     
    239     while (m--)
    240     {
    241         static int x, y;
    242         static char s[50];
    243         
    244         scanf("%s%d%d", s, &x, &y);
    245         
    246         if (s[0] == 'C')
    247             access(tree + x + n), val[x] = y, update(tree + x + n);
    248         else if (s[0] == 'N')
    249             makeRoot(tree + x), access(tree + y), addNeg(tree + y);
    250         else if (s[0] == 'S')
    251             makeRoot(tree + x), access(tree + y), printf("%d
    ", tree[y].sum);
    252         else if (s[1] == 'A')
    253             makeRoot(tree + x), access(tree + y), printf("%d
    ", tree[y].maxi);
    254         else
    255             makeRoot(tree + x), access(tree + y), printf("%d
    ", tree[y].mini);
    256     }
    257 }

    @Author: YouSiki

  • 相关阅读:
    TestNG+maven+idea 环境基本使用
    linux基本命令
    linux -查看cpu 内存 磁盘 端口 进程
    Scanner类、Random类、ArrayList 类
    (四)面向对象
    (三)数组
    (二)流程-循环
    (一)java基础_常量+变量+数据类型+运算符+方法
    SQL (二)
    SQL(一)
  • 原文地址:https://www.cnblogs.com/yousiki/p/6397775.html
Copyright © 2011-2022 走看看