zoukankan      html  css  js  c++  java
  • HYSBZ1036-树链剖分-点权

    树链剖分,点权,单点更改,路径查询。学树链剖分下面这个博文不错

    http://blog.csdn.net/y990041769/article/details/40348013

    线段树必须写的很熟练才行。注意负数

      1 #include <cstdio>
      2 #include <vector>
      3 #include <algorithm>
      4 
      5 using namespace std;
      6 
      7 const int maxn = 3e4+10;
      8 const int INF = 0x3f3f3f3f;
      9 
     10 /////////////////////////////////////
     11 int topw;
     12 int son[maxn],top[maxn],fa[maxn],siz[maxn],id[maxn],dep[maxn];
     13 int val[maxn],pre_val[maxn];
     14 
     15 vector<int> G[maxn];
     16 
     17 void dfs_1(int u,int f,int d)
     18 {
     19     son[u] = 0;
     20     dep[u] = d;
     21     fa[u]  = f;
     22     siz[u] = 1;
     23     for(int i=0;i<G[u].size();i++)
     24     {
     25         int v = G[u][i];
     26         if(v == f) continue;
     27         dfs_1(v,u,d+1);
     28         siz[u] += siz[v];
     29         if(siz[son[u]] < siz[v])
     30         {
     31             son[u] = v;
     32         }
     33     }
     34 }
     35 
     36 void dfs_2(int u,int tp)
     37 {
     38     top[u] = tp;
     39     id[u] = ++topw;
     40     if(son[u]) dfs_2(son[u],tp);
     41     for(int i=0;i<G[u].size();i++)
     42     {
     43         int v = G[u][i];
     44         if(v == fa[u] || v == son[u]) continue;
     45         dfs_2(v,v);
     46     }
     47 }
     48 
     49 ////////////////////////////////////
     50 #define lson l,m,rt<<1
     51 #define rson m+1,r,rt<<1|1
     52 #define root 1,topw,1
     53 
     54 int sum[maxn<<2];
     55 int mx[maxn<<2];
     56 
     57 void push_up(int rt)
     58 {
     59     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
     60     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
     61 }
     62 
     63 void build(int l,int r,int rt)
     64 {
     65     sum[rt] = 0;
     66     mx[rt] = 0;
     67     if(l == r)
     68     {
     69         sum[rt] = val[l];
     70         mx[rt] = val[l];
     71         return ;
     72     }
     73     int m = (l+r)>>1;
     74     build(lson);
     75     build(rson);
     76     push_up(rt);
     77 }
     78 
     79 void update(int pos,int add,int l,int r,int rt)
     80 {
     81     if(l == r)
     82     {
     83         sum[rt] = add;
     84         mx[rt] = add;
     85         return ;
     86     }
     87     int m = (l+r)>>1;
     88     if(pos <= m) update(pos,add,lson);
     89     else         update(pos,add,rson);
     90     push_up(rt);
     91 }
     92 
     93 int query_sum(int L,int R,int l,int r,int rt)
     94 {
     95     if(L <= l && R >= r)
     96     {
     97         return sum[rt];
     98     }
     99     int m = (l+r)>>1 , ans = 0;
    100     if(L <= m) ans += query_sum(L,R,lson);
    101     if(R >  m) ans += query_sum(L,R,rson);
    102     return ans;
    103 }
    104 
    105 int query_max(int L,int R,int l,int r,int rt)
    106 {
    107     if(L <= l && R >= r)
    108     {
    109         //printf("[%d,%d] rt:%d mx:%d
    ",l,r,rt,mx[rt]);
    110         return mx[rt];
    111     }
    112     int m = (l+r)>>1 , ans = -INF;
    113     if(L <= m) ans = max(ans,query_max(L,R,lson));
    114     if(R >  m) ans = max(ans,query_max(L,R,rson));
    115     return ans;
    116 }
    117 
    118 int Find_sum(int u,int v)
    119 {
    120     int fu = top[u],fv = top[v];
    121     int ans = 0;
    122     while(fu != fv)
    123     {
    124         //printf("ans:%d %d %d %d %d
    ",ans,u,fu,v,fv);
    125         if(dep[fu] < dep[fv])
    126         {
    127             swap(u,v);
    128             swap(fu,fv);
    129         }
    130         ans += query_sum(id[fu],id[u],root);
    131         u = fa[fu];
    132         fu = top[u];
    133     }
    134     if(u == v)
    135     {
    136         return ans+query_sum(id[u],id[v],root);
    137     }
    138     else{
    139         if(dep[u] < dep[v]) swap(u,v);
    140         return ans+query_sum(id[v],id[u],root);
    141     }
    142 }
    143 
    144 int Find_max(int u,int v)
    145 {
    146     int fu = top[u],fv = top[v];
    147     int ans = -INF;
    148     while(fu != fv)
    149     {
    150         if(dep[fu] < dep[fv])
    151         {
    152             swap(u,v);
    153             swap(fu,fv);
    154         }
    155         //printf("ans:%d %d %d %d %d
    ",ans,u,fu,v,fv);
    156         //printf("q:%d
    ",query_max(id[fu],id[u],root));
    157         ans = max(ans,query_max(id[fu],id[u],root));
    158         u = fa[fu];
    159         fu = top[u];
    160     }
    161     if(u == v)
    162     {
    163         return max(ans,query_max(id[u],id[v],root));
    164     }
    165     else{
    166         if(dep[u] < dep[v]) swap(u,v);
    167         return max(ans,query_max(id[v],id[u],root));
    168     }
    169 }
    170 
    171 //////////////////////////////////////////
    172 
    173 int N,Q;
    174 int main()
    175 {
    176     freopen("input.in","r",stdin);
    177     while(~scanf("%d",&N))
    178     {
    179         for(int i=1,u,v;i<N;i++)
    180         {
    181             scanf("%d%d",&u,&v);
    182             G[u].push_back(v);
    183             G[v].push_back(u);
    184         }
    185         for(int i=1;i<=N;i++) scanf("%d",&pre_val[i]);
    186         topw = 0;
    187         dfs_1(1,0,1);
    188         dfs_2(1,1);
    189         for(int i=1;i<=N;i++) val[id[i]] = pre_val[i];
    190         build(root);
    191 
    192         scanf("%d",&Q);
    193         char op[10];
    194         int a,b;
    195         while(Q--)
    196         {
    197             scanf("%s%d%d",op,&a,&b);
    198             if(op[0] == 'Q')
    199             {
    200                 if(op[1] == 'M')
    201                 {
    202                     printf("%d
    ",Find_max(a,b));
    203                 }else
    204                 {
    205                     printf("%d
    ",Find_sum(a,b));
    206                 }
    207             }else
    208             {
    209                 update(id[a],b,root);
    210             }
    211         }
    212         for(int i=0;i<=N;i++) G[i].clear();
    213     }
    214 }
  • 相关阅读:
    小说下载器【追书接口】
    C#调用大漠插件,发送QQ和微信消息
    C# 终本案件、综合执行人、裁判文书爬虫
    追书神器API
    一个CookieContainer的拓展类
    利用BlockingCollection实现生产者和消费者队列,实现写文本
    EF SQLite的Like语句,生成为CHARINDEX的解决办法
    ClientKey实现登录QQ空间,并设置背景音乐
    DataTable转换为Model实体对象
    开通博客第一天!
  • 原文地址:https://www.cnblogs.com/helica/p/5670364.html
Copyright © 2011-2022 走看看