zoukankan      html  css  js  c++  java
  • BZOJ4034 T2

    Description

     有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:

    操作 1 :把某个节点 x 的点权增加 a 。
    操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
    操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
     

    Input

     第一行包含两个整数 N, M 。表示点数和操作数。

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

    Output

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

     

    Sample Input

    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

    Sample Output

    6
    9
    13

    HINT

     

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


    会超过 10^6 。
     
     
    正解:树链剖分
    解题报告:
      链剖裸题。
      但是我居然调试了很久!!!先是迷之RE,结果是细节问题。。。然后是迷之WA,结果是中间变量没开long long
      多么痛的领悟。。。
     
     
      1 //It is made by jump~
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <ctime>
      9 #include <vector>
     10 #include <queue>
     11 #include <map>
     12 #include <set>
     13 #ifdef WIN32   
     14 #define OT "%I64d"
     15 #else
     16 #define OT "%lld"
     17 #endif
     18 using namespace std;
     19 typedef long long LL;
     20 const int MAXN = 100011;
     21 const int MAXM = 200011;
     22 int n,m;
     23 int ecnt,cnt;
     24 int first[MAXN],to[MAXM],next[MAXM],id[MAXN],pre[MAXN],last[MAXN],deep[MAXN],father[MAXN],size[MAXN],son[MAXN],top[MAXN];
     25 int num[MAXN];
     26 LL qx,qy;
     27 int ql,qr;
     28 LL ans;
     29 
     30 struct node{
     31     LL add;
     32     LL val;
     33 }t[MAXN*4];
     34 
     35 inline int getint()
     36 {
     37        int w=0,q=0;
     38        char c=getchar();
     39        while((c<'0' || c>'9') && c!='-') c=getchar();
     40        if (c=='-')  q=1, c=getchar();
     41        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
     42        return q ? -w : w;
     43 }
     44 
     45 inline void dfs1(int x,int fa) {
     46     size[x] = 1;  
     47     for(int i = first[x];i;i = next[i]) {
     48     int v = to[i];
     49     if(v != fa){
     50         father[v] = x; deep[v] = deep[x]+1; 
     51         dfs1(v,x);
     52         size[x] += size[v]; if(size[v] > size[son[x]]) son[x] = v;
     53     }
     54     }
     55 }
     56 
     57 inline void dfs2(int x,int fa){
     58     id[x] = ++cnt; pre[cnt]=x; if(son[x]!=0) top[son[x]]=top[x],dfs2(son[x],x);
     59     for(int i = first[x];i;i = next[i]){
     60     int v = to[i];
     61     if(v != fa && v != son[x]) {
     62         top[v]=v;
     63         dfs2(v,x);
     64     }
     65     }
     66     last[x] = cnt;
     67 }
     68 
     69 inline void build(int root,int l,int r){
     70     if(l == r) { t[root].val = num[pre[l]]; return ; }
     71     int mid = (l + r)/2; int lc = root*2,rc = lc+1;
     72     build(lc,l,mid); build(rc,mid+1,r);
     73     t[root].val = t[lc].val + t[rc].val;
     74 }
     75 
     76 inline void update(int root,int l,int r){    
     77     if(ql <= l && qr >= r) { t[root].add += qy; t[root].val += qy*(r-l+1); }
     78     else{
     79     int mid = (l + r)/2;
     80     int lc = root*2,rc = lc + 1;
     81     if(ql <= mid) update(lc,l,mid); if(qr > mid) update(rc,mid+1,r);
     82     t[root].val = t[lc].val + t[rc].val;
     83     t[root].val += t[root].add*(r-l+1);
     84     }  
     85 }
     86 
     87 inline void query(int root,int l,int r,LL lei){
     88     if(ql <= l && qr >= r) {
     89     ans += t[root].val;
     90     ans += (LL)lei*(LL)(r-l+1);
     91     return ;
     92     }
     93     int mid = (l+r)/2; int lc = root*2,rc = lc+1;
     94     if(ql <= mid) query(lc,l,mid,lei+t[root].add); if(qr > mid) query(rc,mid+1,r,lei+t[root].add);
     95 }
     96 
     97 inline void work(int x){
     98     ans=0; 
     99     int f1 = top[x];      
    100     while(f1!=1) {
    101     ql=id[f1]; qr=id[x];
    102     query(1,1,n,0);
    103     x=father[f1]; f1=top[x];
    104     }
    105     ql=1; qr=id[x]; query(1,1,n,0);  
    106     printf(OT"
    ",ans);
    107 }
    108 
    109 inline void solve(){
    110     n = getint(); m = getint();
    111     for(int i=1;i<=n;i++) num[i] = getint();
    112     int x,y;
    113     for(int i = 1;i < n;i++) {
    114     x = getint(); y = getint();
    115     next[++ecnt] = first[x]; first[x] = ecnt; to[ecnt] = y;
    116     next[++ecnt] = first[y]; first[y] = ecnt; to[ecnt] = x;
    117     }
    118 
    119     deep[1]=1; dfs1(1,0); 
    120     top[1]=1; dfs2(1,0);
    121     build(1,1,n);
    122     int ljh; 
    123     for(int i = 1;i <= m;i++) {
    124     ljh = getint();
    125     if(ljh == 1){ 
    126         qx = id[getint()]; qy = getint();  
    127         ql=qx; qr=qx;
    128         update(1,1,n);
    129     }
    130     else if(ljh == 2){
    131         x = getint(); qy = getint();
    132         qr = last[x];  ql = id[x]; 
    133         update(1,1,n);
    134     }
    135     else{
    136         qx=getint(); work(qx);
    137     }
    138     }
    139 }
    140 
    141 int main()
    142 {
    143   solve();
    144   return 0;
    145 }
  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5616448.html
Copyright © 2011-2022 走看看