• 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 }
  • 相关阅读:
    QQ邮箱自动删除邮件脚本
    5ppm高精度自动同步标准化考场时钟系统
    GPS时钟之户外防水防雷细节
    C/C++ Compile Run插件,使用某些头文件出现重定义的错误,解决方法为修改MinGW的路径
    7zip 通过指令压缩 仅存储压缩 分压缩卷 / 对文件夹里的文件进行解压,解压到对应文件名所在的文件夹上
    循环队列FIFO
    cglib和jdk代理的字节码生成配置
    SpringXML的beans标签后的一串网址相关的属性有什么用
    service和server这两个单词的区别
    没有代码提示的地方,前后引用记得用复制不要手打
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5616448.html
Copyright © 2020-2023  润新知