• P3833 [SHOI2012]魔法树


    题目链接:https://www.luogu.org/problem/P3833

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <stdbool.h>
      5 #include <stdlib.h>
      6 #include <string>
      7 #include <string.h>
      8 #include <stack>
      9 #include <queue>
     10 #include <set>
     11 #include <map>
     12 #include <math.h>
     13 
     14 #define INF 0x3f3f3f3f
     15 #define LL long long
     16 using namespace std;
     17 
     18 const int maxn = 100050;
     19 
     20 struct Edge{
     21     int to,next;
     22 }edge[maxn*4];
     23 
     24 int head[maxn],tot;
     25 
     26 void add_edge(int u,int v){
     27     edge[++tot] = Edge{v,head[u]};
     28     head[u] = tot;
     29     //edge[tot] = Edge{u,head[v]};
     30     //head[v] = tot++;
     31 }
     32 
     33 int v[maxn];
     34 int fa[maxn];
     35 int siz[maxn];
     36 int dep[maxn];
     37 int son[maxn];
     38 
     39 void dfs1(int u,int f){
     40     fa[u] = f;
     41     dep[u] = dep[f] + 1;
     42     siz[u] = 1;
     43     int maxsize = -1;
     44     for (int i=head[u];~i;i=edge[i].next){
     45         int v = edge[i].to;
     46         if (v == f){
     47             continue;
     48         }
     49         dfs1(v,u);
     50         siz[u] += siz[v];
     51         if (siz[v] > maxsize){
     52             maxsize = siz[v];
     53             son[u] = v;
     54         }
     55     }
     56 }
     57 
     58 
     59 int tim;
     60 int dfn[maxn];
     61 int top[maxn];
     62 int w[maxn];
     63 
     64 void dfs2(int u,int t){
     65     dfn[u] = ++tim;
     66     top[u] = t;
     67     w[tim] = v[u];
     68     if (!son[u]){
     69         return ;
     70     }
     71     dfs2(son[u],t);
     72     for (int i=head[u];~i;i=edge[i].next){
     73         int v = edge[i].to;
     74         if (v == fa[u] || v == son[u]){
     75             continue;
     76         }
     77         dfs2(v,v);
     78     }
     79 }
     80 
     81 struct segment_tree{
     82     int l,r;
     83     LL val;
     84     int lazy;
     85 }tree[maxn*4];
     86 
     87 void pushup(int nod){
     88     tree[nod].val = (tree[nod<<1].val + tree[(nod<<1)+1].val);
     89 }
     90 
     91 void pushdown(int nod){
     92     tree[nod<<1].lazy += tree[nod].lazy;
     93     tree[(nod<<1)+1].lazy += tree[nod].lazy;
     94     tree[nod<<1].val += (tree[nod<<1].r-tree[nod<<1].l + 1) * tree[nod].lazy;
     95     tree[(nod<<1)+1].val += (tree[(nod<<1)+1].r-tree[(nod<<1)+1].l+1) * tree[nod].lazy;
     96     tree[nod].lazy = 0;
     97 }
     98 
     99 void build (int l,int r,int nod){
    100     tree[nod].l = l;
    101     tree[nod].r = r;
    102     if (l == r){
    103         tree[nod].lazy = 0;
    104         tree[nod].val = w[l];
    105         return ;
    106     }
    107     int mid = (l + r) >> 1;
    108     build(l,mid,nod<<1);
    109     build(mid+1,r,(nod<<1)+1);
    110     pushup(nod);
    111 }
    112 
    113 
    114 void modify(int x,int y,int z,int k=1){
    115     int l = tree[k].l, r = tree[k].r;
    116     if (x <= l && y>=r){
    117         tree[k].lazy += z;
    118         tree[k].val += (r-l+1) * z;
    119         return ;
    120     }
    121     if (tree[k].lazy){
    122         pushdown(k);
    123     }
    124     int mid = (l + r) >> 1;
    125     if (x <= mid){
    126         modify(x,y,z,k<<1);
    127     }
    128     if (y > mid){
    129         modify(x,y,z,(k<<1)+1);
    130     }
    131     pushup(k);
    132 }
    133 
    134 LL query(int x,int y,int k=1){
    135     int l = tree[k].l,r = tree[k].r;
    136     if (x <= l && y >= r){
    137         return tree[k].val;
    138     }
    139     if (tree[k].lazy){
    140         pushdown(k);
    141     }
    142     int mid = (l + r) >> 1;
    143     LL sum = 0;
    144     if (x <= mid){
    145         sum += query(x,y,k<<1);
    146     }
    147     if (y > mid){
    148         sum += query(x,y,(k<<1)+1);
    149     }
    150     return sum;
    151 }
    152 
    153 LL q_query(int x){
    154     return query(dfn[x],dfn[x]+siz[x]-1);
    155 }
    156 
    157 void mchain(int x,int y,int z) {
    158     while (top[x] != top[y]) {
    159         if (dep[top[x]] < dep[top[y]])
    160             swap(x, y);
    161         modify(dfn[top[x]], dfn[x], z);
    162         x = fa[top[x]];
    163     }
    164     if (dep[x] > dep[y])
    165         swap(x, y);
    166     modify(dfn[x], dfn[y], z);
    167 }
    168 
    169 
    170 int main(){
    171     int n;
    172     scanf("%d",&n);
    173     memset(head,-1, sizeof(head));
    174     for (int i=1;i<=n-1;i++){
    175         int x,y;
    176         scanf("%d%d",&x,&y);
    177         add_edge(x,y);
    178         add_edge(y,x);
    179     }
    180     dfs1(0,0);
    181     dfs2(0,0);
    182     build(1,n,1);
    183     int T;
    184     scanf("%d",&T);
    185     while (T--){
    186         char s[4];
    187         int x,y,z;
    188         scanf("%s",s);
    189         if (s[0] == 'A'){
    190             scanf("%d%d%d",&x,&y,&z);
    191             mchain(x,y,z);
    192         }
    193         if (s[0] == 'Q') {
    194             scanf("%d",&x);
    195             printf("%lld
    ",q_query(x));
    196         }
    197     }
    198     return 0;
    199 }
  • 相关阅读:
    11G-使用跨平台增量备份减少可移动表空间的停机时间 XTTS (Doc ID 1389592.1)
    如何在asm上定位数据块
    log file switch (checkpoint incomplete)
    踩坑记录(git)-误提交target文件夹删除办法
    踩坑记录(java)-双层增强for调用remove(obj)报错 java.util.ConcurrentModificationException(并发修改异常)
    Zookeeper服务端的创建及简单的客户端创建节点
    SpringAOP(注解方式实现面向切面编程)之常用Before、After、Around
    EasyExcel示例(阿里巴巴)基于Maven
    Redis简单命令(部分示例代码)
    sqlserver日志处理不当而造成的隐患
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11449158.html
Copyright © 2020-2023  润新知