zoukankan      html  css  js  c++  java
  • hdu 6162 Ch’s gift(树链剖分+主席树)

    题目链接:hdu 6162 Ch’s gift

    题意:

    给你一棵树,树上每个点有一个权值,现在有m个询问,每次询问给你一个s,t,L,R,问你从s到t的路径上,权值在[L,R]内的总和为多少。

    题解:

    我感觉我写复杂了,用树链剖分来维护路径,然后用主席树来建立权值线段树乱搞。

     1 #include<bits/stdc++.h>
     2 #define mst(a,b) memset(a,b,sizeof(a))
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 typedef long long ll;
     5 using namespace std;
     6 
     7 const int N=1e5+7;
     8 int dep[N],sz[N],hs[N],top[N],tid[N],fid[N],fa[N],idx;
     9 int n,m,pp,x,y,a[N],g[N],nxt[2*N],v[2*N],ed;
    10 int hsh[N*4],h_ed,root[N];
    11 
    12 struct Node{int l,r;ll sum;}T[N*40];
    13 int cnt;
    14 ll ans;
    15 struct Q{int s,t,a,b;}q[N];
    16 
    17 int gid(int x){return lower_bound(hsh+1,hsh+1+h_ed,x)-hsh;}
    18 
    19 void add(int &x,int y,int idx,int val,int l=1,int r=h_ed)
    20 {
    21     T[x=++cnt]=T[y],T[x].sum+=val;
    22     if(l==r)return;
    23     int mid=l+r>>1;
    24     if(idx<=mid)add(T[x].l,T[y].l,idx,val,l,mid);
    25     else add(T[x].r,T[y].r,idx,val,mid+1,r);
    26 }
    27 
    28 ll ask(int x,int y,int L,int R,int l=1,int r=h_ed)
    29 {
    30     if(L<=l&&r<=R)return T[y].sum-T[x].sum;
    31     int mid=l+r>>1;ll an=0;
    32     if(L<=mid)an+=ask(T[x].l,T[y].l,L,R,l,mid);
    33     if(R>mid)an+=ask(T[x].r,T[y].r,L,R,mid+1,r);
    34     return an;
    35 }
    36 
    37 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
    38 
    39 void dfs1(int u,int pre){
    40     dep[u]=dep[pre]+1,hs[u]=0,fa[u]=pre,sz[u]=1;
    41     for(int i=g[u];i;i=nxt[i])if(v[i]!=pre)
    42     dfs1(v[i],u),sz[u]+=sz[v[i]],hs[u]=(sz[v[i]]>sz[hs[u]])?v[i]:hs[u];
    43 }
    44 void dfs2(int u,int tp){
    45     top[u]=tp,tid[u]=++idx,fid[idx]=u;
    46     if(hs[u])dfs2(hs[u],tp);
    47     for(int i=g[u];i;i=nxt[i])
    48     if(v[i]!=fa[u]&&v[i]!=hs[u])dfs2(v[i],v[i]);
    49 }
    50 
    51 void up(int x,int y,int a,int b){
    52     int fx=top[x],fy=top[y];
    53     while(fx!=fy){
    54         if(dep[fx]>dep[fy])
    55         {
    56             int xx=tid[fx],yy=tid[x];
    57             if(xx>yy)swap(xx,yy);
    58             ans+=ask(root[xx-1],root[yy],a,b);
    59             x=fa[fx],fx=top[x];
    60         }
    61         else {
    62             int xx=tid[fy],yy=tid[y];
    63             if(xx>yy)swap(xx,yy);
    64             ans+=ask(root[xx-1],root[yy],a,b);
    65             y=fa[fy],fy=top[y];
    66         }
    67     }
    68     if(dep[x]>dep[y])x^=y,y^=x,x^=y;
    69     int xx=tid[x],yy=tid[y];
    70     if(xx>yy)swap(xx,yy);
    71     ans+=ask(root[xx-1],root[yy],a,b);
    72 }
    73 
    74 int main(){
    75     while(~scanf("%d%d",&n,&m)){
    76         F(i,1,n)scanf("%d",a+i),hsh[i]=a[i];
    77         cnt=0,ed=0,h_ed=n;F(i,1,n)g[i]=0;
    78         F(i,2,n)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
    79         F(i,1,m)
    80         {
    81             scanf("%d%d%d%d",&q[i].s,&q[i].t,&q[i].a,&q[i].b);
    82             hsh[++h_ed]=q[i].a,hsh[++h_ed]=q[i].b;
    83         }
    84         sort(hsh+1,hsh+1+h_ed),h_ed=unique(hsh+1,hsh+1+h_ed)-hsh-1;
    85         dfs1(1,0),idx=0,dfs2(1,1);
    86         F(i,1,idx)add(root[i],root[i-1],gid(a[fid[i]]),a[fid[i]]);
    87         F(i,1,m){
    88             int S=q[i].s,T=q[i].t,a=q[i].a,b=q[i].b;
    89             ans=0,up(S,T,gid(a),gid(b));
    90             printf("%lld%c",ans," 
    "[i==m]);
    91         }
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    textarea 滚动条属性设置
    js触发asp.net的Button的Onclick事件
    Asp.Net获取远程数据并保存为文件的简单代码
    《WEB标准拾遗系列》
    .NET基础拾遗系列第一篇
    .NET基础拾遗系列第三篇
    你的知识如何管理(必须看)
    .NET基础拾遗系列第二篇
    随便划两笔
    Sql server 事务的两种用法 (转)
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7413081.html
Copyright © 2011-2022 走看看