zoukankan      html  css  js  c++  java
  • 洛谷——P3178 [HAOI2015]树上操作

    https://www.luogu.org/problem/show?pid=3178#sub

    题目描述

    有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a 。操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

    输入输出格式

    输入格式:

    第一行包含两个整数 N, M 。表示点数和操作数。接下来一行 N 个整数,表示树中节点的初始权值。接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

    输出格式:

    对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

    输入输出样例

    输入样例#1:
    5 5
    1 2 3 4 5
    1 2
    1 4
    2 3
    2 5
    3 3
    1 2 1
    3 5
    2 1 2
    3 3
    输出样例#1:
    6
    9
    13

    说明

    对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

    会超过 10^6 。

    树剖模板练习

      1 #include <algorithm>
      2 #include <cstdio>
      3 
      4 #define LL long long
      5 
      6 using namespace std;
      7 
      8 const LL N(100000+15);
      9 const LL M(100000+15);
     10 LL n,m,u,v,w,op,val[N];
     11 
     12 LL head[N],sumedge;
     13 struct Edge
     14 {
     15     LL u,v,next;
     16     Edge(LL u=0,LL v=0,LL next=0):
     17         u(u),v(v),next(next){}
     18 }edge[M<<1];
     19 inline void ins(LL u,LL v)
     20 {
     21     edge[++sumedge]=Edge(u,v,head[u]);
     22     head[u]=sumedge;
     23 }
     24 
     25 LL size[N],deep[N],dad[N],son[N],top[N],dfn[N],id[N],cnt;
     26 void DFS(LL x,LL father,LL deepth)
     27 {
     28     deep[x]=deepth;
     29     dad[x]=father;
     30     size[x]=1;
     31     for(LL i=head[x];i;i=edge[i].next)
     32     {
     33         LL v=edge[i].v;
     34         if(dad[x]==v) continue;
     35         DFS(v,x,deepth+1);
     36         size[x]+=size[v];
     37         if(size[son[x]]<size[v]) son[x]=v;
     38     }
     39 }
     40 void DFS_(LL x,LL Top)
     41 {
     42     top[x]=Top;
     43     id[x]=++cnt,dfn[cnt]=x;
     44     if(son[x]) DFS_(son[x],Top);
     45     for(LL i=head[x];i;i=edge[i].next)
     46     {
     47         LL v=edge[i].v;
     48         if(dad[x]!=v&&son[x]!=v) DFS_(v,v);
     49     }
     50 }
     51 
     52 struct Tree
     53 {
     54     LL l,r,mid,flag,val;
     55 }tree[N<<2];
     56 inline void Tree_up(LL now)
     57 {
     58     tree[now].val=tree[now<<1].val+tree[now<<1|1].val;
     59 }
     60 void Tree_down(LL now)
     61 {
     62     tree[now<<1].flag+=tree[now].flag;
     63     tree[now<<1].val+=(tree[now].mid-tree[now].l+1)*tree[now].flag;
     64     tree[now<<1|1].flag+=tree[now].flag;
     65     tree[now<<1|1].val+=(tree[now].r-tree[now].mid)*tree[now].flag;
     66     tree[now].flag=0;
     67 }
     68 void Tree_build(LL now,LL l,LL r)
     69 {
     70     tree[now].l=l;tree[now].r=r;
     71     if(l==r)
     72     {
     73         tree[now].val=val[dfn[l]];
     74         return ;
     75     }
     76     tree[now].mid=l+r>>1;
     77     Tree_build(now<<1,l,tree[now].mid);
     78     Tree_build(now<<1|1,tree[now].mid+1,r);
     79     Tree_up(now);
     80 }
     81 void Tree_change(LL now,LL l,LL r,LL x)
     82 {
     83     
     84     if(tree[now].l==l&&tree[now].r==r)
     85     {
     86         tree[now].flag+=x;
     87         tree[now].val+=(r-l+1)*x;
     88         return ;
     89     }
     90     if(tree[now].flag) Tree_down(now);
     91     if(tree[now].mid>=r) Tree_change(now<<1,l,r,x);
     92     else if(tree[now].mid<l) Tree_change(now<<1|1,l,r,x);
     93     else
     94     {
     95         Tree_change(now<<1,l,tree[now].mid,x);
     96         Tree_change(now<<1|1,tree[now].mid+1,r,x);
     97     }
     98     Tree_up(now);
     99 }
    100 LL Tree_query(LL now,int l,int r)
    101 {
    102     if(tree[now].l==l&&tree[now].r==r)
    103         return tree[now].val;
    104     if(tree[now].flag) Tree_down(now);
    105     if(tree[now].mid>=r) return Tree_query(now<<1,l,r);
    106     else if(tree[now].mid<l) return Tree_query(now<<1|1,l,r);
    107     else return Tree_query(now<<1,l,tree[now].mid)+Tree_query(now<<1|1,tree[now].mid+1,r);
    108 }
    109 
    110 LL List_query(LL x,LL y)
    111 {
    112     LL ret=0;
    113     for(;top[x]!=top[y];x=dad[top[x]])
    114     {
    115         if(deep[top[x]]<deep[top[y]]) swap(x,y);
    116         ret+=Tree_query(1,id[top[x]],id[x]);
    117     }
    118     if(deep[x]<deep[y]) swap(x,y);
    119     ret+=Tree_query(1,id[y],id[x]);
    120     return ret;
    121 }
    122 
    123 int if_,ch;
    124 inline void read (LL &x)
    125 {
    126     if_=x=0;ch=getchar();
    127     for(;ch<'0'||ch>'9';ch=getchar())
    128         if(ch=='-') if_=1;
    129     for(;ch>='0'&&ch<='9';ch=getchar())
    130         x=x*10+ch-'0';
    131     if(if_) x=(~x)+1;
    132 }
    133 
    134 int main()
    135 {
    136     read(n); read(m);
    137     for(LL i=1;i<=n;i++)
    138         read(val[i]);
    139     for(LL i=1;i<n;i++)
    140     {
    141         read(u); read(v);
    142         ins(u,v),ins(v,u);
    143     }
    144     DFS(1,0,1);DFS_(1,1);
    145     Tree_build(1,1,n);
    146     for(;m--;)
    147     {
    148         read(op);
    149         if(op==1)
    150         {
    151             read(u); read(w);
    152             Tree_change(1,id[u],id[u],w);
    153         }
    154         else if(op==2)
    155         {
    156             read(u); read(w);
    157             Tree_change(1,id[u],id[u]+size[u]-1,w);
    158         }
    159         else
    160         {
    161             read(u);
    162             printf("%lld
    ",List_query(u,1));
    163         }
    164     }
    165     return 0;
    166 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    [学习笔记] SSD代码笔记 + EifficientNet backbone 练习
    [论文理解] CornerNet: Detecting Objects as Paired Keypoints
    [torch] torch.contiguous
    [tensorflow] tf2.0 简单例子
    [大坑]Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
    本机Jenkins的使用
    安全工具acunetix使用
    cv2.matchTemplate()函数的应用,匹配图片后画出矩形
    python将PNG格式的图片转化成为jpg
    Python实现FTP文件的上传和下载
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7044493.html
Copyright © 2011-2022 走看看