zoukankan      html  css  js  c++  java
  • [SHOI2012]魔法树

    原题链接:https://www.luogu.org/problemnew/show/P3833

    题目背景

    SHOI2012 D2T3

    题目描述

    Harry Potter 新学了一种魔法:可以让改变树上的果子个数。满心欢喜的他找到了一个巨大的果树,来试验他的新法术。

    这棵果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u],保证有fa[u] < u。初始时,这棵果树上的果子都被 Dumbledore 用魔法清除掉了,所以这个果树的每个节点上都没有果子(即0个果子)。

    不幸的是,Harry 的法术学得不到位,只能对树上一段路径的节点上的果子个数统一增加一定的数量。也就是说,Harry 的魔法可以这样描述:

    Add u v d

    表示将点u和v之间的路径上的所有节点的果子个数都加上d。

    接下来,为了方便检验 Harry 的魔法是否成功,你需要告诉他在释放魔法的过程中的一些有关果树的信息:

    Query u

    表示当前果树中,以点u为根的子树中,总共有多少个果子?

    输入输出格式

    输入格式:

    第一行一个正整数N (1 ≤ N ≤ 100000),表示果树的节点总数,节点以0,1,…,N − 1标号,0一定代表根节点。

    接下来N − 1行,每行两个整数a,b (0 ≤ a < b < N),表示a是b的父亲。

    接下来是一个正整数Q(1 ≤ ? ≤ 100000),表示共有Q次操作。

    后面跟着Q行,每行是以下两种中的一种:

    1. A u v d,表示将u到v的路径上的所有节点的果子数加上d;0 ≤ u,v <N,0 < d < 100000

    2. Q u,表示询问以u为根的子树中的总果子数,注意是包括u本身的。

    输出格式:

    对于所有的Query操作,依次输出询问的答案,每行一个。答案可能会超过2^32 ,但不会超过10^15 。

    输入输出样例

    输入样例
    4
    0 1
    1 2
    2 3
    4
    A 1 3 1
    Q 0
    Q 1
    Q 2
    输出样例
    3
    3 2

    树剖裸题.....记得开long long....

      1 #include <cstdio>
      2 #include <iostream>
      3 #define ll long long
      4 using namespace std;
      5 const int N=1500000+10;
      6 int v[N*2],nxt[N*2],first[N],cnt;
      7 int pos[N],dep[N],fa[N],top[N],siz[N],son[N],sz;
      8 int n,m;
      9 struct seg{
     10     int l,r;
     11     ll s,t;
     12 }tr[N*4];
     13 
     14 void read(int &x){
     15     x=0;int f=1;char c=getchar();
     16     while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
     17     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
     18     x*=f;
     19 }
     20 
     21 void add(int a,int b){
     22     v[++cnt]=b;
     23     nxt[cnt]=first[a];
     24     first[a]=cnt;
     25 }
     26 
     27 void dfs1(int x){
     28     siz[x]=1;
     29     for(int i=first[x];i;i=nxt[i]){
     30         if(fa[x]==v[i]) continue;
     31         dep[v[i]]=dep[x]+1;
     32         fa[v[i]]=x;
     33         dfs1(v[i]);
     34         siz[x]+=siz[v[i]];
     35         if(siz[v[i]]>siz[son[x]]) son[x]=v[i];
     36     }
     37 }
     38 
     39 void dfs2(int x,int y){
     40     pos[x]=++sz;top[x]=y;
     41     int k=son[x];
     42     if(!k) return ;
     43     dfs2(k,y);
     44     for(int i=first[x];i;i=nxt[i]) if(dep[v[i]]>dep[x]&&k!=v[i]) dfs2(v[i],v[i]); 
     45 }
     46 
     47 void build(int k,int s,int t){
     48     tr[k].l=s;tr[k].r=t;
     49     if(s==t) return ;
     50     int mid=(s+t)/2;
     51     build(k*2,s,mid);build(k*2+1,mid+1,t); 
     52 }
     53 
     54 void push(int k){
     55     int x=tr[k].r-tr[k].l+1;
     56     tr[k*2].t+=tr[k].t;
     57     tr[k*2+1].t+=tr[k].t;
     58     tr[k*2].s+=1ll*tr[k].t*(x-(x/2));
     59     tr[k*2+1].s+=1ll*tr[k].t*(x/2);
     60     tr[k].t=0;
     61 }
     62 
     63 void ud(int k,int s,int t,ll v){
     64     int l=tr[k].l,r=tr[k].r;
     65     if(s==l&&t==r){
     66         tr[k].t+=v;
     67         tr[k].s+=1ll*v*(r-l+1);
     68         return ;
     69     }
     70     if(tr[k].t) push(k);
     71     int mid=(l+r)/2;
     72     if(s>mid) ud(k*2+1,s,t,v);
     73     else if(t<=mid) ud(k*2,s,t,v);
     74     else {
     75         ud(k*2,s,mid,v);
     76         ud(k*2+1,mid+1,t,v);
     77     }
     78     tr[k].s=tr[k*2].s+tr[k*2+1].s;
     79 }
     80 
     81 void solud(int x,int y,ll v){
     82     while(top[x]!=top[y]){
     83         if(dep[top[x]]<dep[top[y]]) swap(x,y);
     84         ud(1,pos[top[x]],pos[x],v);
     85         x=fa[top[x]];
     86     }
     87     if(pos[x]>pos[y]) swap(x,y);
     88     ud(1,pos[x],pos[y],v);
     89 }
     90 
     91 ll qy(int k,int s,int t){
     92     int l=tr[k].l,r=tr[k].r;
     93     if(s==l&&t==r) return tr[k].s;
     94     if(tr[k].t) push(k);
     95     int mid=(l+r)/2;
     96     if(s>mid) return qy(k*2+1,s,t);
     97     else if(t<=mid) return qy(k*2,s,t);
     98     else return qy(k*2,s,mid)+qy(k*2+1,mid+1,t);
     99 }
    100 
    101 int main(){
    102     read(n);
    103     for(int i=1;i<n;i++){
    104         int x,y;
    105         read(x);read(y);
    106         add(x+1,y+1);add(y+1,x+1);
    107     }
    108     dfs1(1);dfs2(1,1);
    109     build(1,1,n);
    110     int q;read(q);
    111     for(int i=1;i<=q;i++){
    112         char c[10];
    113         int x,y;
    114         ll z;
    115         scanf("%s",c);read(x);++x;
    116         if(c[0]=='Q') printf("%lld
    ",qy(1,pos[x],pos[x]+siz[x]-1));
    117         else{
    118             read(y);scanf("%lld",&z);++y;
    119             solud(x,y,z);
    120         }
    121     }
    122     return 0;
    123 }
    View Code
  • 相关阅读:
    单例模式 & Init(allocWithZone:)
    Go 初体验
    Go 初体验
    beego 初体验
    beego 初体验
    beego 初体验
    beego 初体验
    beego 初体验
    beego 初体验
    beego 初体验
  • 原文地址:https://www.cnblogs.com/lyf2/p/8640202.html
Copyright © 2011-2022 走看看