• 4034: [HAOI2015]树上操作


    4034: [HAOI2015]树上操作

    链接

    思路:

      树链剖分。操作:单点修改,路径查询,子树修改。

    代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<cctype>
      7 
      8 using namespace std;
      9 
     10 const int N = 100100;
     11 typedef long long LL;
     12 
     13 struct Edge{
     14     int to,nxt;
     15     Edge() {}
     16     Edge(int a,int b) {to = a,nxt = b;}
     17 }e[N<<1];
     18 int head[N],tot;
     19 LL sum[N<<2],tag[N<<2],w[N],data[N];
     20 int pos[N],siz[N],son[N],bel[N],deth[N],fa[N];
     21 int tn;
     22 
     23 inline int read() {
     24     int x = 0,f = 1;char ch = getchar();
     25     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f = -1;
     26     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
     27     return x * f;
     28 }
     29 void add_edge(int u,int v) {
     30     e[++tot] = Edge(v,head[u]);head[u] = tot;
     31     e[++tot] = Edge(u,head[v]);head[v] = tot;
     32 }
     33 void dfs1(int u,int pa) {
     34     siz[u] = 1;
     35     deth[u] = deth[pa] + 1;
     36     fa[u] = pa;
     37     for (int i=head[u]; i; i=e[i].nxt) {
     38         int v = e[i].to;
     39         if (v==pa) continue;
     40         dfs1(v,u);
     41         siz[u] += siz[v];
     42         if (!son[u] || siz[son[u]]<siz[v]) son[u] = v;
     43     }
     44 }
     45 void dfs2(int u,int top) {
     46     bel[u] = top;
     47     pos[u] = ++tn;
     48     data[pos[u]] = w[u];
     49     if (!son[u]) return; 
     50     dfs2(son[u],top);
     51     for (int i=head[u]; i; i=e[i].nxt) {
     52         int v = e[i].to;
     53         if (v==fa[u] || v==son[u]) continue;
     54         dfs2(v,v);
     55     }
     56 }
     57 
     58 #define lson l,mid,rt<<1
     59 #define rson mid+1,r,rt<<1|1
     60 
     61 void pushup(int rt) {
     62     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     63 }
     64 void pushdown(int rt,int len) {
     65     if (tag[rt]) {
     66         sum[rt<<1] += 1ll * tag[rt] * (len-len/2);tag[rt<<1] += tag[rt];
     67         sum[rt<<1|1] += 1ll * tag[rt] * (len/2);tag[rt<<1|1] += tag[rt];
     68         tag[rt] = 0;
     69     }
     70 }
     71 void build(int l,int r,int rt) {
     72     if (l==r) {
     73         sum[rt] = data[l];
     74         return ;
     75     }
     76     int mid = (l + r) / 2;
     77     build (lson);
     78     build (rson);
     79     pushup(rt);
     80 }
     81 void update(int l,int r,int rt,int L,int R,LL x) {
     82     if (L <= l && r <= R) {
     83         sum[rt] += 1ll * (r - l + 1) * x;
     84         tag[rt] += x;
     85         return ;
     86     }
     87     pushdown(rt,r-l+1);
     88     int mid = (l + r) / 2;
     89     if (L <= mid) update(lson,L,R,x);
     90     if (R > mid)  update(rson,L,R,x);
     91     pushup(rt);
     92 }
     93 LL query(int l,int r,int rt,int L,int R) {
     94     if (L <= l && r <= R) {
     95         return sum[rt];
     96     }
     97     int mid = (l + r) / 2;
     98     LL ret = 0;
     99     pushdown(rt,r-l+1);
    100     if (L <= mid) ret += query(lson,L,R);
    101     if (R > mid)  ret += query(rson,L,R);
    102     return ret;
    103 }
    104 void Ask(int x,int y) {
    105     LL ans = 0;
    106     while (bel[x] != bel[y]) {
    107         if (deth[bel[x]] < deth[bel[y]]) swap(x,y);
    108         ans += query(1,tn,1,pos[bel[x]],pos[x]);
    109         x = fa[bel[x]];
    110     }
    111     if (deth[x] < deth[y]) swap(x,y);
    112     ans += query(1,tn,1,pos[y],pos[x]);
    113     printf("%lld
    ",ans);
    114 }
    115 int main() {
    116     int n = read(),m = read();
    117     for (int i=1; i<=n; ++i) w[i] = read();
    118     for (int i=1; i<n; ++i) {
    119         int u = read(),v = read();
    120         add_edge(u,v);
    121     }
    122     dfs1(1,0);
    123     dfs2(1,1);
    124     build(1,tn,1);
    125     LL a;
    126     while (m--) {
    127         int opt = read(),x = read();
    128         if (opt == 1) {
    129             a = read();
    130             update(1,tn,1,pos[x],pos[x],a);    
    131         }
    132         else if (opt==2) {
    133             a = read();
    134             update(1,tn,1,pos[x],pos[x]+siz[x]-1,a);
    135         }
    136         else Ask(x,1);
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    纳尼?不用码代码,就可回归主流程,一只海豚就可以做到
    教育产品-组件化视觉设计实践
    从整理看视觉设计(网易云课堂我的学习中心-微专业视觉优化)
    搜索意图识别浅析
    如何配置使用Dnsmasq
    如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染技术!
    PAT 1024. Palindromic Number
    PAT 1023. Have Fun with Numbers
    PAT 1022. Digital Library
    PAT 1021. Deepest Root
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9062811.html
Copyright © 2020-2023  润新知