• [HAOI2015]树上操作 -树链剖分


                                         1963. [HAOI2015]树上操作

    【题目描述】

    有一棵点数为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)。

    【输出格式】

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

    【样例输入】

    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

    【样例输出】

    6

    9

    13

    【提示】

    对于30%的数据,N,M<=1000

    对于50%的数据,N,M<=100000且数据随机。

    对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。

    注意long long就好了 

    把它当做树剖模板来做,听说并查集也能做

      1 #include <ctype.h>
      2 #include <cstdio>
      3 
      4 typedef long long LL;
      5 
      6 const int MAXN=100010;
      7 
      8 int n,m,inr;
      9 
     10 LL a[MAXN];
     11 
     12 struct SegmentTree {
     13     int l,r;
     14     LL val,tag;
     15 };
     16 SegmentTree t[MAXN<<2];
     17 
     18 struct data {
     19     int to;
     20     int next;
     21 };
     22 data E[MAXN*10];
     23 
     24 int head[MAXN<<1],tot;
     25 
     26 int siz[MAXN],son[MAXN],fa[MAXN],id[MAXN],dep[MAXN],top[MAXN],rank[MAXN],mx[MAXN];
     27 
     28 inline void read(int&x) {
     29     int f=1;register char c=getchar();
     30     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
     31     for(;isdigit(c);x=x*10+c-48,c=getchar());
     32     x=x*f;
     33 }
     34 
     35 inline void readl(LL&x) {
     36     int f=1;register char c=getchar();
     37     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
     38     for(;isdigit(c);x=x*10+c-48,c=getchar());
     39     x=x*f;
     40 }
     41 
     42 inline void add(int x,int y) {
     43     E[++tot].to=y;
     44     E[tot].next=head[x];
     45     head[x]=tot;
     46 }
     47 
     48 inline int max(int a,int b) {
     49     return a<b?b:a;
     50 }
     51 
     52 inline void swap(int&x,int&y) {
     53     int t=x;x=y;y=t;
     54     return;
     55 }
     56 
     57 inline void dfs_1(int now,int f) {
     58     dep[now]=dep[f]+1;
     59     siz[now]=1;
     60     fa[now]=f;
     61     for(register int i=head[now];i;i=E[i].next) {
     62         int to=E[i].to;
     63         if(to==f) continue;
     64         dfs_1(to,now);
     65         siz[now]+=siz[to];
     66         if(son[now]==-1||siz[son[now]]<siz[to]) son[now]=to;
     67     }
     68 }
     69 
     70 inline void dfs_2(int now,int sym) {
     71     id[now]=++inr;
     72     top[now]=sym;
     73     rank[id[now]]=now;
     74     if(son[now]==-1) return;
     75     dfs_2(son[now],sym);
     76     for(int i=head[now];i;i=E[i].next) {
     77         int to=E[i].to;
     78         if(to!=son[now]&&to!=fa[now])
     79           dfs_2(to,to);
     80     }
     81     return;
     82 }
     83 
     84 inline void build_tree(int now,int l,int r) {
     85     t[now].l=l,t[now].r=r;
     86     if(l==r) {
     87         t[now].val=a[rank[l]];
     88         return;
     89     }
     90     int mid=(l+r)>>1;
     91     build_tree(now<<1,l,mid);
     92     build_tree(now<<1|1,mid+1,r);
     93     t[now].val=t[now<<1].val+t[now<<1|1].val;
     94 }
     95 
     96 inline void down(int now) {
     97     t[now<<1].val+=(t[now<<1].r-t[now<<1].l+1)*t[now].tag;
     98     t[now<<1|1].val+=(t[now<<1|1].r-t[now<<1|1].l+1)*t[now].tag;
     99     t[now<<1].tag+=t[now].tag;
    100     t[now<<1|1].tag+=t[now].tag;
    101     t[now].tag=0;
    102 }
    103 
    104 inline void modify(int now,int l,int r,LL val) {
    105     if(l<=t[now].l&&r>=t[now].r) {
    106         t[now].tag+=val;
    107         t[now].val+=(t[now].r-t[now].l+1)*val;
    108         return;
    109     }
    110     down(now);
    111     int mid=(t[now].l+t[now].r)>>1;
    112     if(l<=mid) modify(now<<1,l,r,val);
    113     if(r>mid) modify(now<<1|1,l,r,val);
    114     t[now].val=t[now<<1].val+t[now<<1|1].val;
    115 }
    116 
    117 inline LL query(int now,int l,int r) {
    118     LL ans=0;
    119     if(l<=t[now].l&&r>=t[now].r) return t[now].val;
    120     down(now);
    121     int mid=(t[now].l+t[now].r)>>1;
    122     if(l<=mid) ans+=query(now<<1,l,r);
    123     if(r>mid) ans+=query(now<<1|1,l,r);
    124     return ans;
    125 }
    126 
    127 inline LL Pre_query(int u,int v) {
    128     LL ans=0;
    129     while(top[u]!=top[v]) {
    130         if(dep[top[u]]<dep[top[v]]) swap(u,v);
    131         ans+=query(1,id[top[u]],id[u]);
    132         u=fa[top[u]];
    133     }
    134     if(dep[u]<dep[v]) swap(u,v);
    135     ans+=query(1,id[v],id[u]);
    136     return ans;
    137 }
    138 
    139 int hh() {
    140     freopen("haoi2015_t2.in","r",stdin);
    141     freopen("haoi2015_t2.out","w",stdout);
    142     int x,y,opt;
    143     read(n);read(m);
    144     for(register int i=1;i<=n;++i) son[i]=-1,readl(a[i]);
    145     for(register int i=1;i<n;++i) {
    146         read(x);read(y);
    147         add(x,y);add(y,x);
    148     }
    149     dfs_1(1,0);
    150     dfs_2(1,1);
    151     build_tree(1,1,inr);
    152     LL p;
    153     for(register int i=1;i<=m;++i) {
    154         read(opt);read(x);
    155             if(opt==1) {
    156                 readl(p);
    157                 modify(1,id[x],id[x],p);
    158             }
    159             else if(opt==2) {
    160                 readl(p);
    161                 modify(1,id[x],id[x]+siz[x]-1,p);
    162             }
    163             else {
    164                 LL ans=Pre_query(1,x);
    165                 printf("%lld
    ",ans);
    166             }
    167     }
    168     return 0;
    169 }
    170 
    171 int sb=hh();
    172 int main() {;}
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    Oracle中使用游标详解
    arc140 vp 记录
    CF1710D Recover theTree
    2022.8 做题记录
    21noip赛前20天 day10 简要题解
    2022.7.22 AGC028F&CF1463F&P7740
    arc141 vp 记录
    2022.7.25 AGC027F&AGC032F&AGC013F
    2022.7.21 AGC046D&P6790&AGC041F
    2022.7.20 AGC052D&P4338&AGC033E
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7409854.html
Copyright © 2020-2023  润新知