zoukankan      html  css  js  c++  java
  • Nowcoder 练习赛26E 树上路径

    Description

    传送门

    给出一个n个点的树,1号节点为根节点,每个点有一个权值
    你需要支持以下操作
    1.将以u为根的子树内节点(包括u)的权值加val

    2.将(u, v)路径上的节点权值加val
    3.询问(u, v)路径上节点的权值两两相乘的和
     

    Solution

    维护 平方和与 数值和

    修改 : 假如修改时有节点a, b, c, 增加t, 那么$sumsq = a^2 + b^2 + c^2 + 2*t*(a + b+c) + 3 * t^2$

    所以对于所有的修改, $sumsq = sumsq + 2*t*sum + (r-l+1)*t^2$

    这样平方和与数值和就可以维护了

    查询只需要输出 $(sum * sum - sumsq) / 2$

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define ll long long
      5 #define rd read()
      6 #define lson nd << 1
      7 #define rson nd << 1 | 1
      8 using namespace std;
      9 
     10 const int N = 1e5 + 5;
     11 const ll mod = 1e9 + 7;
     12 
     13 int n, m;
     14 int top[N], size[N], son[N], f[N], dep[N], cnt;
     15 int head[N], tot;
     16 int A[N], a[N], id[N];
     17 int Li[N << 2], Ri[N << 2];
     18 ll sum[N << 2], sum2[N << 2], inv, add[N << 2];
     19 
     20 struct edge{
     21     int nxt, to;
     22 }e[N << 1];
     23 
     24 int read() {
     25     int X = 0, p = 1; char c = getchar();
     26     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
     27     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
     28     return X * p;
     29 }
     30 
     31 void added(int u, int v) {
     32     e[++tot].to = v;
     33     e[tot].nxt = head[u];
     34     head[u] = tot;
     35 }
     36 
     37 void dfs1(int u) {
     38     size[u] = 1;
     39     for(int i = head[u]; i; i = e[i].nxt) {
     40         int nt = e[i].to;
     41         if(nt == f[u]) continue;
     42         dep[nt] = dep[u] + 1;
     43         f[nt] = u;
     44         dfs1(nt);
     45         size[u] += size[nt];
     46         if(size[nt] > size[son[u]]) son[u] = nt;
     47     }
     48 }
     49 
     50 void dfs2(int u) {
     51     id[u] = ++cnt;
     52     A[cnt] = a[u];
     53     if(!son[u]) return;
     54     top[son[u]] = top[u];
     55     dfs2(son[u]);
     56     for(int i = head[u]; i; i = e[i].nxt) {
     57         int nt = e[i].to;
     58         if(nt == f[u] || nt == son[u]) continue;
     59         top[nt] = nt;
     60         dfs2(nt);
     61     }
     62 }
     63 
     64 void pushdown(int nd) {
     65     if(add[nd]) {
     66         sum2[lson] += (2 * sum[lson] * add[nd] % mod + (Ri[lson] - Li[lson] + 1) * add[nd] % mod * add[nd] % mod) % mod;
     67         sum2[lson] %= mod;
     68         sum2[rson] += (2 * sum[rson] * add[nd] % mod + (Ri[rson] - Li[rson] + 1) * add[nd] % mod * add[nd] % mod) % mod;
     69         sum2[rson] %= mod;
     70         
     71         sum[lson] += (Ri[lson] - Li[lson] + 1) * add[nd] % mod;
     72         sum[lson] %= mod;
     73         sum[rson] += (Ri[rson] - Li[rson] + 1) * add[nd] % mod;
     74         sum[rson] %= mod;
     75 
     76         add[lson] += add[nd];
     77         add[rson] += add[nd];
     78         add[lson] %= mod;
     79         add[rson] %= mod;
     80         add[nd] = 0;
     81     }
     82 }
     83 
     84 void update(int nd) {
     85     sum[nd] = (sum[lson] + sum[rson]) % mod;
     86     sum2[nd] = (sum2[lson] + sum2[rson]) % mod;
     87 }
     88 
     89 void build(int l, int r, int nd) {
     90     if(l == r) {
     91         Li[nd] = l;
     92         Ri[nd] = r;
     93         sum[nd] = A[l];
     94         sum2[nd] = A[l] * A[l] % mod;
     95         return;
     96     }
     97     Li[nd] = l;
     98     Ri[nd] = r;
     99     int mid =(l + r) >> 1;
    100     build(l, mid, lson);
    101     build(mid + 1, r, rson);
    102     update(nd);
    103 }
    104 
    105 void modify(int L, int R, int d, int l, int r, int nd) {
    106     if(L <= l && r <= R) {
    107         sum2[nd] += (2 * sum[nd] * d % mod + (r - l + 1) * d % mod * d % mod) % mod;
    108         sum2[nd] %= mod;
    109         sum[nd] += 1LL * d * (r - l + 1) % mod;
    110         sum[nd] %= mod;
    111         add[nd] += d;
    112         add[nd] %= mod;
    113         return;
    114     }
    115     pushdown(nd);
    116     int mid = (l + r) >> 1;
    117     if(mid >= L) modify(L, R, d, l, mid, lson);
    118     if(mid < R) modify(L, R, d, mid + 1, r, rson);
    119     update(nd);
    120 }
    121 
    122 ll query(int L, int R, int l, int r, int nd) {
    123     if(L <= l && r <= R) return sum[nd];
    124     int mid = (l + r) >> 1;
    125     ll re = 0;
    126     pushdown(nd);
    127     if(mid >= L) re = (re + query(L, R, l, mid, lson)) % mod;
    128     if(mid < R) re = (re + query(L, R, mid + 1, r, rson)) % mod;
    129     return re;
    130 }
    131 
    132 ll query2(int L, int R, int l, int r, int nd) {
    133     if(L <= l && r <= R) return sum2[nd];
    134     int mid = (l + r) >> 1;
    135     ll re = 0;
    136     pushdown(nd);
    137     if(mid >= L) re = (re + query2(L, R, l, mid, lson)) % mod;
    138     if(mid < R) re = (re + query2(L, R, mid + 1, r, rson)) % mod;
    139     return re;
    140 }
    141 
    142 ll query_po(int x, int y) {
    143     ll re = 0, tmp, sum = 0;
    144     for(; top[x] != top[y];) {
    145         if(dep[top[x]] < dep[top[y]]) swap(x, y);
    146         tmp = query(id[top[x]], id[x], 1, n, 1);
    147         sum = (sum + tmp % mod) % mod;
    148         tmp = query2(id[top[x]], id[x], 1, n, 1);
    149         re = (re - tmp) % mod;
    150         x = f[top[x]];
    151     }
    152     if(dep[x] < dep[y]) swap(x, y);
    153     tmp = query(id[y], id[x], 1, n, 1);
    154     sum = (sum + tmp) % mod;
    155     tmp = query2(id[y], id[x], 1, n, 1);
    156     re = (re - tmp) % mod;
    157     re = (re + sum * sum % mod) % mod;
    158     re = (re % mod + mod) % mod;
    159     re = re * inv % mod;
    160     return re;
    161 }
    162 
    163 void modify_po(int x, int y, int d) {
    164     for(; top[x] != top[y];) {
    165         if(dep[top[x]] < dep[top[y]]) swap(x, y);
    166         modify(id[top[x]], id[x], d, 1, n, 1);
    167         x = f[top[x]];
    168     }
    169     if(dep[x] < dep[y]) swap(x, y);
    170     modify(id[y], id[x], d, 1, n, 1);
    171 }
    172 
    173 ll fc(ll ta, ll b) {
    174     ll re = 0;
    175     for(; b; b >>= 1, ta = (ta + ta) % mod) if( b & 1) re = (re + ta) % mod;
    176     return re;
    177 }
    178 
    179 ll fpow(ll ta, ll b) {
    180     ll re = 1;
    181     for(; b; b >>= 1, ta = fc(ta, ta)) if(b & 1) re = fc(re, ta);
    182     return re;
    183 }
    184 
    185 int main()
    186 {
    187     n = rd; m = rd;
    188     for(int i = 1; i <= n; ++i) a[i] = rd;
    189     for(int i = 1; i < n; ++i) {
    190         int u = rd, v = rd;
    191         added(u, v); added(v, u);
    192     }
    193     dfs1(1); 
    194     top[1] = 1;
    195     dfs2(1);
    196     build(1, n, 1);
    197     inv = fpow(2, mod - 2);
    198     for(int i = 1; i <= m; ++i) {
    199         int k = rd;
    200         if(k == 1) {
    201             int u = rd, val = rd;
    202             modify(id[u], id[u] + size[u] - 1, val, 1, n, 1);
    203         }
    204         if(k == 2) {
    205             int u = rd, v = rd, val = rd;
    206             modify_po(u, v, val);
    207         }
    208         if(k == 3) {
    209             int u = rd, v = rd;
    210             printf("%lld
    ", query_po(u, v));
    211         }
    212     }
    213 }
    View Code
  • 相关阅读:
    Feed back TFS 2017 RC upgrade status to product team in product group 2017.03.01
    TFS Training for Kunlun bank (http://www.klb.cn/) 微软研发流程(ALM)管理培训会议(昆仑银行) 2016.09.21
    微软DevOps软件开发高级培训课程(深圳站) 2016.04.06
    秒杀系统架构设计
    程序员职业规划
    程序员跳槽时,会遇到哪些套路?
    程序员3大点
    程序员37个小贴士
    程序员6大点
    程序员面试 10 大潜规则
  • 原文地址:https://www.cnblogs.com/cychester/p/9607835.html
Copyright © 2011-2022 走看看