• poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询


      1 /**
      2 problem: http://poj.org/problem?id=2763
      3 **/
      4 #include<stdio.h>
      5 #include<stdlib.h>
      6 #include<string.h>
      7 #include<vector>
      8 using namespace std;
      9 
     10 const int MAXN = 100005;
     11 
     12 template <typename T>
     13 class SegmentTree {
     14 private:
     15     struct Node {
     16         int left, right;
     17         T sum, lazy;
     18     } node[MAXN << 2];
     19     T data[MAXN];
     20     void pushUp(int root) {
     21         node[root].sum = node[root << 1].sum + node[root << 1 | 1].sum;
     22     }
     23     void pushDown(int root) {
     24         if(node[root].left == node[root].right) return;
     25         int lson = root << 1;
     26         int rson = root << 1 | 1;
     27         node[lson].sum = node[root].lazy * (node[lson].right - node[lson].left + 1);
     28         node[rson].sum = node[root].lazy * (node[rson].right - node[rson].left + 1);
     29         node[lson].lazy = node[root].lazy;
     30         node[rson].lazy = node[root].lazy;
     31         node[root].lazy = 0;
     32     }
     33 public:
     34     void build(int left, int right, int root = 1) {
     35         node[root].left = left;
     36         node[root].right = right;
     37         node[root].lazy = 0;
     38         if(left == right) {
     39             node[root].sum = data[left];
     40         } else {
     41             int mid = (left + right) >> 1;
     42             build(left, mid, root << 1);
     43             build(mid + 1, right, root << 1 | 1);
     44             pushUp(root);
     45         }
     46     }
     47     void update(int left, int right, T value, int root = 1) {
     48         int lson = root << 1;
     49         int rson = root << 1 | 1;
     50         if(node[root].lazy) pushDown(root);
     51         if(node[root].left == left && node[root].right == right) {
     52             node[root].sum = value * (right - left + 1);
     53             node[root].lazy = value;
     54             return ;
     55         }
     56         if(left >= node[rson].left) {
     57             update(left, right, value, rson);
     58         } else if(right <= node[lson].right) {
     59             update(left, right, value, lson);
     60         } else {
     61             update(left, node[lson].right, value, lson);
     62             update(node[rson].left, right, value, rson);
     63         }
     64         pushUp(root);
     65     }
     66     T query(int left, int right, int root = 1) {
     67         int lson = root << 1;
     68         int rson = root << 1 | 1;
     69         if(node[root].lazy) pushDown(root);
     70         if(node[root].left == left && node[root].right == right) {
     71             return node[root].sum;
     72         }
     73         if(left >= node[rson].left) {
     74             return query(left, right, rson);
     75         } else if(right <= node[lson].right) {
     76             return query(left, right, lson);
     77         } else {
     78             return query(left, node[lson].right, lson) + query(node[rson].left, right, rson);
     79         }
     80     }
     81     void clear(int n, const vector<int> &d) {
     82         for(int i = 1; i <= n; i ++) {
     83             this->data[i] = d[i];
     84         }
     85         build(1, n);
     86     }
     87 };
     88 
     89 template <typename T>
     90 class TreeToLink {
     91 private:
     92     struct Point {
     93         int size, son, depth, father, top, newId;
     94         T data;
     95     } point[MAXN];
     96     struct Edge {
     97         int to, next;
     98     } edge[MAXN << 1];
     99     int oldId[MAXN], first[MAXN], sign, sumOfPoint, cnt;
    100     SegmentTree<T> st;
    101     void dfs1(int u, int father = 0, int depth = 1) {
    102         point[u].depth = depth;
    103         point[u].father = father;
    104         point[u].size = 1;
    105         int maxson = -1;
    106         for(int i = first[u]; i != -1; i = edge[i].next) {
    107             int to = edge[i].to;
    108             if(to == father) continue;
    109             dfs1(to, u, depth + 1);
    110             point[u].size += point[to].size;
    111             if(point[to].size > maxson) {
    112                 point[u].son = to;
    113                 maxson = point[to].size;
    114             }
    115         }
    116     }
    117     void dfs2(int u, int top) {
    118         point[u].newId = ++cnt;
    119         oldId[cnt] = u;
    120         point[u].top = top;
    121         if(point[u].son == -1) {
    122             return ;
    123         }
    124         dfs2(point[u].son, top);
    125         for(int i = first[u]; i != -1; i = edge[i].next) {
    126             int to = edge[i].to;
    127             if(to == point[u].son || to == point[u].father) continue;
    128             dfs2(to, to);
    129         }
    130     }
    131 public:
    132     void clear(int n) {
    133         sumOfPoint = n;
    134         sign = 0;
    135         cnt = 0;
    136         for(int i = 1; i <= n; i ++) {
    137             first[i] = -1;
    138             point[i].son = -1;
    139 //            scanf("%d", &point[i].data); // input
    140             point[i].data = 0;
    141         }
    142     }
    143     void addEdgeOneWay(int u, int v) {
    144         edge[sign].to = v;
    145         edge[sign].next = first[u];
    146         first[u] = sign ++;
    147     }
    148     void addEdgeTwoWay(int u, int v) {
    149         addEdgeOneWay(u, v);
    150         addEdgeOneWay(v, u);
    151     }
    152     void preWork(int x = 1) {
    153         dfs1(x);
    154         dfs2(x, x);
    155         vector<int> data(sumOfPoint + 1);
    156         for(int i = 1; i <= sumOfPoint; i ++) {
    157             data[i] = point[oldId[i]].data;
    158         }
    159         st.clear(sumOfPoint, data);
    160     }
    161     void updatePath(int x, int y, T z){
    162         while(point[x].top != point[y].top){
    163             if(point[point[x].top].depth < point[point[y].top].depth)
    164                 swap(x, y);
    165             st.update(point[point[x].top].newId, point[x].newId, z);
    166             x = point[point[x].top].father;
    167         }
    168         if(point[x].depth > point[y].depth)
    169             swap(x, y);
    170         st.update(point[x].newId, point[y].newId, z);
    171     }
    172     T queryPath(int x, int y){
    173         T ans = 0;
    174         while(point[x].top != point[y].top){
    175             if(point[point[x].top].depth < point[point[y].top].depth)
    176                 swap(x, y);
    177             ans += st.query(point[point[x].top].newId, point[x].newId);
    178             x = point[point[x].top].father;
    179         }
    180         if(x == y) return ans; // Edge
    181         if(point[x].depth > point[y].depth)
    182             swap(x, y);
    183 //        ans += st.query(point[x].newId, point[y].newId); // Point
    184         ans += st.query(point[point[x].son].newId, point[y].newId); // Edge
    185         return ans;
    186     }
    187     void updateSon(int x, T z){
    188         st.update(point[x].newId, point[x].newId + point[x].size - 1, z);
    189     }
    190     T querySon(int x){
    191         return st.query(point[x].newId, point[x].newId + point[x].size - 1);
    192     }
    193     T queryPoint(int x) {
    194         return queryPath(x, x);
    195     }
    196     void updatePoint(int x, T z) {
    197         updatePath(x, x, z);
    198     }
    199     bool deeper(int u, int v){
    200         return point[u].depth > point[v].depth;
    201     }
    202 };
    203 
    204 class Solution {
    205 private:
    206     int n, q, s;
    207     TreeToLink<int> ttl;
    208     struct Edge{
    209         int u, v, w;
    210     }edge[MAXN];
    211 public:
    212     void solve() {
    213         scanf("%d%d%d", &n, &q, &s);
    214         ttl.clear(n);
    215         for(int i = 1; i < n; i ++){
    216             scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
    217             ttl.addEdgeTwoWay(edge[i].u, edge[i].v);
    218         }
    219         ttl.preWork(s);
    220         for(int i = 1; i < n; i ++){
    221             if(ttl.deeper(edge[i].u, edge[i].v)){
    222                 swap(edge[i].u, edge[i].v);
    223             }
    224             ttl.updatePoint(edge[i].v, edge[i].w);
    225         }
    226         int now = s;
    227         for(int i = 0, a, b, c; i < q; i ++){
    228             scanf("%d%d", &a, &b);
    229             if(a == 1){
    230                 scanf("%d", &c);
    231                 ttl.updatePoint(edge[b].v, c);
    232             }else{
    233                 printf("%d
    ", ttl.queryPath(now, b));
    234                 now = b;
    235             }
    236         }
    237     }
    238 } DarkScoCu;
    239 
    240 int main() {
    241     DarkScoCu.solve();
    242     return 0;
    243 }
  • 相关阅读:
    python 时间等待
    python threading多线程
    c 字符串的结束标志
    c 输出是自动显示输出类型
    c 的占位符
    c数据类型
    游戏引擎
    java 数据类型
    python 读写json数据
    python 多线程_thread
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10699152.html
Copyright © 2020-2023  润新知