zoukankan      html  css  js  c++  java
  • HDU 6162 Ch's gift(树链剖分+线段树)

    题意:

    已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和。

    思路:

    用树链剖分将树映射到线段树上,线段树上维护3个值,max,min和sum即可。

    接下来就是一个简单的线段树上的查询。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 using namespace std;
     12 typedef long long ll;
     13 const int INF = 0x3f3f3f3f;
     14 const int maxn=1e5+5;
     15 
     16 int n, m, pos;
     17 int s, e, a, b;
     18 int val[maxn],fa[maxn],son[maxn],dep[maxn],num[maxn],top[maxn],p[maxn],fp[maxn];
     19 ll ans[maxn];
     20 vector<int> G[maxn];
     21 
     22 struct node
     23 {
     24     int l, r;
     25     ll mx,mi,sum;
     26 }t[maxn<<2];
     27 
     28 void dfs(int u, int pre, int d)
     29 {
     30     dep[u]=d;
     31     son[u]=-1;
     32     num[u]=1;
     33     fa[u]=pre;
     34     for(int i=0;i<G[u].size();i++)
     35     {
     36         int v=G[u][i];
     37         if(v==pre) continue;
     38         dfs(v,u,d+1);
     39         num[u]+=num[v];
     40         if(son[u]==-1 || num[son[u]]<num[v])
     41             son[u]=v;
     42     }
     43 }
     44 
     45 void getpos(int u, int sp)
     46 {
     47     top[u]=sp;
     48     if(son[u]!=-1)
     49     {
     50         p[u]=pos++;
     51         fp[p[u]]=u;
     52         getpos(son[u],sp);
     53     }
     54     else
     55     {
     56         p[u]=pos++;
     57         fp[p[u]]=u;
     58         return;
     59     }
     60     for(int i=0;i<G[u].size();i++)
     61     {
     62         int v=G[u][i];
     63         if(son[u]==v || v==fa[u])  continue;
     64         getpos(v,v);
     65     }
     66 }
     67 
     68 void PushUp(int o)
     69 {
     70     t[o].mx=max(t[o<<1].mx,t[o<<1|1].mx);
     71     t[o].mi=min(t[o<<1].mi,t[o<<1|1].mi);
     72     t[o].sum=t[o<<1].sum+t[o<<1|1].sum;
     73 }
     74 
     75 void build(int l, int r, int o)
     76 {
     77     t[o].l=l;
     78     t[o].r=r;
     79     if(l==r)
     80     {
     81         t[o].mx=t[o].mi=t[o].sum=val[fp[l]];
     82         return;
     83     }
     84     int mid=(l+r)>>1;
     85     build(l,mid,o<<1);
     86     build(mid+1,r,o<<1|1);
     87     PushUp(o);
     88 }
     89 
     90 ll query(int ql, int qr, int l, int r, int o)
     91 {
     92     int mid=(l+r)>>1;
     93     if(ql<=l && qr>=r)
     94     {
     95         if(t[o].mx<a || t[o].mi>b)  return 0;
     96         if(t[o].mi>=a && t[o].mx<=b)  return t[o].sum;
     97         return query(ql,qr,l,mid,o<<1)+query(ql,qr,mid+1,r,o<<1|1);
     98     }
     99     ll ans=0;
    100     if(ql<=mid)  ans+=query(ql,qr,l,mid,o<<1);
    101     if(qr>mid)   ans+=query(ql,qr,mid+1,r,o<<1|1);
    102     return ans;
    103 }
    104 
    105 ll lca(int x,int y)
    106 {
    107     ll ans=0;
    108     while(top[x]!=top[y])
    109     {
    110         if(dep[top[x]]<dep[top[y]])  swap(x,y);
    111         ans+=query(p[top[x]],p[x],1,n,1);
    112         x=fa[top[x]];
    113     }
    114     if(dep[x]>dep[y])  swap(x,y);
    115     ans+=query(p[x],p[y],1,n,1);
    116     return ans;
    117 }
    118 
    119 int main()
    120 {
    121     //freopen("in.txt","r",stdin);
    122     while(~scanf("%d%d",&n,&m))
    123     {
    124         for(int i=1;i<=n;i++)  {G[i].clear();scanf("%d",&val[i]);}
    125         for(int i=1;i<n;i++)
    126         {
    127             int u,v;
    128             scanf("%d%d",&u,&v);
    129             G[u].push_back(v);
    130             G[v].push_back(u);
    131         }
    132         dfs(1,-1,0);
    133         pos=1;
    134         getpos(1,1);
    135         build(1,n,1);
    136         for(int i=1;i<=m;i++)
    137         {
    138             scanf("%d%d%d%d",&s,&e,&a,&b);
    139             ans[i]=lca(s,e);
    140         }
    141         for(int i=1;i<=m;i++)
    142             printf("%lld%c",ans[i],i==m?'
    ':' ');
    143     }
    144     return 0;
    145 }
  • 相关阅读:
    使用curses管理基于文本的屏幕--(四)
    让Debian服务器支持jsp程序
    使用curses管理基于文本的屏幕--(五)
    SQL Server DT问与答
    ExtJS4.x treegrid 控件复选框的研究
    动态查找表之二叉排序树
    应届毕业生求职,注意事项
    windows编码约定
    JavaJDBC数据库开发
    Windows桌面应用开发字符串的使用
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7451506.html
Copyright © 2011-2022 走看看