zoukankan      html  css  js  c++  java
  • HDU 3966 基础树链剖分

    题意:给一棵树,并给定各个点权的值,然后有3种操作:
    I C1 C2 K: 把C1与C2的路径上的所有点权值加上K
    D C1 C2 K:把C1与C2的路径上的所有点权值减去K
    Q C:查询节点编号为C的权值

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 using namespace std;
      7 #define N 50010
      8 #define ls o<<1
      9 #define rs o<<1|1
     10 #define define_m int m=(l+r)>>1
     11 #define ll long long
     12 int n , m , q , first[N] , k;
     13 
     14 struct Edge{
     15     int y , next;
     16     Edge(){}
     17     Edge(int y , int next):y(y),next(next){}
     18 }e[N<<1];
     19 
     20 void add_edge(int x , int y)
     21 {
     22     e[k] = Edge(y , first[x]);
     23     first[x] = k++;
     24 }
     25 
     26 int sz[N] , fa[N] , son[N] , top[N] , dep[N] , id[N] , number;
     27 void dfs(int u , int f , int d)
     28 {
     29     fa[u] = f;
     30     sz[u] = 1 , dep[u] = d , son[u] =0;
     31     int maxn = 0;
     32     for(int i=first[u] ; ~i ; i=e[i].next){
     33         int v= e[i].y;
     34         if(v == f) continue;
     35         dfs(v , u , d+1);
     36         sz[u] += sz[v];
     37         if(sz[v]>maxn) son[u] = v , maxn=sz[v];
     38     }
     39 }
     40 
     41 void dfs1(int u , int f , int head)
     42 {
     43     top[u] = head;
     44     if(son[u]){
     45         id[son[u]] = ++number;
     46         dfs1(son[u] , u , head);
     47     }
     48     for(int i=first[u] ; ~i ; i=e[i].next){
     49         int v = e[i].y;
     50         if(v == f || v == son[u]) continue;
     51         id[v] = ++number;
     52         dfs1(v , u , v);
     53     }
     54 }
     55 
     56 int val[N] , add[N<<2] , siz[N<<2];
     57 ll sum[N<<2];
     58 
     59 void push_up(int o){sum[o] = sum[ls]+sum[rs];}
     60 
     61 void push_down(int o)
     62 {
     63     if(add[o]){
     64         add[ls] += add[o] , add[rs] += add[o];
     65         sum[ls] += (ll)add[o]*siz[ls] , sum[rs] += (ll)add[o]*siz[rs];
     66         add[o] = 0;
     67     }
     68 }
     69 
     70 void build(int o , int l , int r)
     71 {
     72     add[o] = 0 , siz[o] = r-l+1;
     73     if(l==r){
     74         sum[o] = (ll)val[l];
     75         return ;
     76     }
     77     define_m;
     78     build(ls , l , m);
     79     build(rs , m+1 , r);
     80     push_up(o);
     81 }
     82 
     83 void update(int o , int l , int r , int s , int t , int v)
     84 {
     85     if(l>=s && r<=t){
     86         sum[o] += (ll)siz[o]*v;
     87         add[o] += v;
     88         return ;
     89     }
     90     define_m;
     91     push_down(o);
     92     if(m>=s) update(ls , l , m , s , t , v);
     93     if(m<t) update(rs , m+1 , r , s , t , v);
     94     push_up(o);
     95 }
     96 
     97 ll query(int o , int l , int r , int p)
     98 {
     99     if(l==r && l==p) return sum[o];
    100     push_down(o);
    101     define_m;
    102     if(m>=p) return query(ls , l , m, p);
    103     else return query(rs , m+1 , r , p);
    104 }
    105 
    106 void updatePath(int u , int v , int change)
    107 {
    108     int top1 = top[u] , top2 = top[v];
    109     while(top1!=top2){
    110         if(dep[top1]<dep[top2]){
    111             swap(top1 , top2);
    112             swap(u , v);
    113         }
    114         update(1 , 1 , n , id[top1] , id[u] , change);
    115         u = fa[top1];
    116         top1 = top[u];
    117     }
    118     
    119     if(dep[u]<dep[v]) swap(u , v);
    120     update(1 , 1 , n , id[v] , id[u] , change);
    121     
    122 }
    123 
    124 char str[4];
    125 
    126 int main()
    127 {
    128    // freopen("in.txt" , "r" , stdin);
    129     while(~scanf("%d%d%d" ,&n , &m , &q))
    130     {
    131         for(int i=1 ; i<=n ; i++) scanf("%d" , val+i);
    132         memset(first , -1 , sizeof(first));
    133         k = 0;
    134         while(m--){
    135             int u , v;
    136             scanf("%d%d" , &u , &v);
    137             add_edge(u,v);
    138             add_edge(v,u);
    139         }
    140         number = 0;
    141         dfs(1 , 0 , 1);
    142         id[1] = ++number;
    143         dfs1(1 , 0 , 1);
    144       //  for(int i=1 ; i<=n ; i++) cout<<i<<" "<<son[i]<<" "<<id[i]<<endl;
    145         int tmp[N];
    146         for(int i=1 ; i<=n ; i++) tmp[i]=val[i];
    147         for(int i=1 ; i<=n ; i++) val[id[i]] = tmp[i];
    148         build(1 , 1 , n);
    149         for(int i=0 ; i<q ; i++){
    150             int s , t , v;
    151             scanf("%s" , str);
    152             if(str[0] == 'Q'){
    153                 scanf("%d" , &v);
    154                 ll ans = query(1 , 1 , n , id[v]);
    155                 printf("%d
    " , (int)ans);
    156             }else if(str[0]=='I'){
    157                 scanf("%d%d%d" , &s , &t , &v);
    158                 updatePath(s , t , v);
    159             }else{
    160                 scanf("%d%d%d" , &s , &t , &v);
    161                 updatePath(s , t , -v);
    162             }
    163         }
    164     }
    165     return 0;
    166 }
  • 相关阅读:
    一个不确定内容的数组,统计每个元素出现的次数的方法
    WebStorm配置TSLint
    angualr 项目环境搭建
    angular6 导出json数据到excal表
    angular6 引用echart第一次数据不显示解决
    angular6 开发实践基础知识汇总
    angular6实现对象转换数组对象
    angular 实现左侧和顶部固定定位布局
    ASP.NET MVC 全局异常
    IOC容器之Autofac
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4763943.html
Copyright © 2011-2022 走看看