• HDU 3966 RE 树链剖分 线段树 Aragorn's Story


    题意:

    给出一棵树,每个顶点上有一个权值。

    操作:选择一条路径,并将路径上所有的点的权值同时加或减某个数。

    查询:某个点的当前权值

    分析:

    树链剖分完毕后,就是简单的线段树区间更新。

    提交的时候注意要要加一句扩栈的代码,用C++提交。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 
      6 void read(int& x) {
      7     x = 0;
      8     char c = ' ';
      9     while(c < '0' || c > '9') c = getchar();
     10     while('0' <= c && c <= '9') {
     11         x = x * 10 + c - '0';
     12         c = getchar();
     13     }
     14 }
     15 
     16 const int maxn = 50000 + 10;
     17 const int maxnode = maxn * 4;
     18 
     19 struct Edge
     20 {
     21     int v, nxt;
     22     Edge() {}
     23     Edge(int v, int nxt) :v(v), nxt(nxt) {}
     24 };
     25 
     26 int n, m, q;
     27 int a[maxn];
     28 
     29 int ecnt, head[maxn];
     30 Edge edges[maxn * 2];
     31 
     32 void AddEdge(int u, int v) {
     33     edges[++ecnt] = Edge(v, head[u]);
     34     head[u] = ecnt;
     35     edges[++ecnt] = Edge(u, head[v]);
     36     head[v] = ecnt;
     37 }
     38 
     39 int dep[maxn], fa[maxn], son[maxn], sz[maxn];
     40 
     41 int tot, id[maxn], pos[maxn], top[maxn];
     42 
     43 void dfs(int u) {
     44     sz[u] = 1; son[u] = -1;
     45     for(int i = head[u]; i; i = edges[i].nxt) {
     46         int v = edges[i].v;
     47         if(v == fa[u]) continue;
     48         fa[v] = u;
     49         dep[v] = dep[u] + 1;
     50         dfs(v);
     51         sz[u] += sz[v];
     52         if(son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v;
     53     }
     54 }
     55 
     56 void dfs2(int u, int tp) {
     57     top[u] = tp;
     58     id[u] = ++tot;
     59     pos[tot] = u;
     60     if(son[u] == -1) return;
     61     if(son[u]) dfs2(son[u], tp);
     62     for(int i = head[u]; i; i = edges[i].nxt) {
     63         int v = edges[i].v;
     64         if(v == fa[u] || v == son[u]) continue;
     65         dfs2(v, v);
     66     }
     67 }
     68 
     69 int sumv[maxnode], addv[maxnode];
     70 char cmd[10];
     71 
     72 void pushup(int o) { sumv[o] = sumv[o<<1] + sumv[o<<1|1]; }
     73 
     74 void build(int o, int L, int R) {
     75     if(L == R) { sumv[o] = a[pos[L]]; return; }
     76     int M = (L + R) / 2;
     77     build(o<<1, L, M);
     78     build(o<<1|1, M+1, R);
     79     pushup(o);
     80 }
     81 
     82 void pushdown(int o, int L, int R) {
     83     if(addv[o]) {
     84         addv[o<<1] += addv[o];
     85         addv[o<<1|1] += addv[o];
     86         int M = (L + R) / 2;
     87         sumv[o<<1] += (M - L + 1) * addv[o];
     88         sumv[o<<1|1] += (R - M) * addv[o];
     89         addv[o] = 0;
     90     }
     91 }
     92 
     93 void update(int o, int L, int R, int qL, int qR, int v) {
     94     if(qL <= L && R <= qR) {
     95         sumv[o] += (R - L + 1) * v;
     96         addv[o] += v;
     97         return;
     98     }
     99     pushdown(o, L, R);
    100     int M = (L + R) / 2;
    101     if(qL <= M) update(o<<1, L, M, qL, qR, v);
    102     if(qR > M) update(o<<1|1, M+1, R, qL, qR, v);
    103     pushup(o);
    104 }
    105 
    106 void UPDATE(int u, int v, int val) {
    107     int t1 = top[u], t2 = top[v];
    108     while(t1 != t2) {
    109         if(dep[t1] < dep[t2]) { swap(u, v); swap(t1, t2); }
    110         update(1, 1, n, id[t1], id[u], val);
    111         u = fa[t1]; t1 = top[u];
    112     }
    113     if(dep[u] > dep[v]) swap(u, v);
    114     update(1, 1, n, id[u], id[v], val);
    115 }
    116 
    117 int query(int o, int L, int R, int p) {
    118     if(L == R) return sumv[o];
    119     pushdown(o, L, R);
    120     int M = (L + R) / 2;
    121     if(p <= M) return query(o<<1, L, M, p);
    122     else return query(o<<1|1, M+1, R, p);
    123 }
    124 
    125 int main()
    126 {
    127     while(scanf("%d%d%d", &n, &m, &q) == 3) {
    128         for(int i = 1; i <= n; i++) read(a[i]);
    129 
    130         memset(head, 0, sizeof(head));
    131         ecnt = 0;
    132         for(int i = 1; i < n; i++) {
    133             int u, v; read(u); read(v);
    134             AddEdge(u, v);
    135         }
    136 
    137         dfs(1);
    138         tot = 0;
    139         dfs2(1, 1);
    140 
    141         memset(addv, 0, sizeof(addv));
    142         build(1, 1, n);
    143 
    144         while(q--) {
    145             scanf("%s", cmd);
    146             int u, v, d;
    147             read(u);
    148             if(cmd[0] == 'Q') {
    149                 printf("%d
    ", query(1, 1, n, id[u]));
    150             } else {
    151                 read(v); read(d);
    152                 if(cmd[0] == 'D') d = -d;
    153                 UPDATE(u, v, d);
    154             }
    155         }
    156     }
    157 
    158     return 0;
    159 }
    代码君
  • 相关阅读:
    在不打开excel的情况下用python执行excel
    Python中xlrd、xlwt、win32com模块对xls文件的读写操作
    [已解决]报错:have mixed types. Specify dtype option on import or set low_memory=False
    [已解决]报错:xlrd.compdoc.CompDocError: Workbook: size exceeds expected 17920 bytes; corrupt?
    使用Pandas读取大型Excel文件
    [转]jmeter实战
    webService(SOAP)性能测试脚本
    jmeter正则表达式提取器--关联
    Data Set Config配置元件
    压力测试涉及到的参数
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4707822.html
Copyright © 2020-2023  润新知