Ch’s gift

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2534    Accepted Submission(s): 887

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=6162

Problem Description

Mr.
Cui is working off-campus and he misses his girl friend very much.
After a whole night tossing and turning, he decides to get to his girl
friend's city and of course, with well-chosen gifts. He knows neither
too low the price could a gift be since his girl friend won't like it,
nor too high of it since he might consider not worth to do. So he will
only buy gifts whose price is between [a,b].
There are n cities in
the country and (n-1) bi-directional roads. Each city can be reached
from any other city. In the ith city, there is a specialty of price ci
Cui could buy as a gift. Cui buy at most 1 gift in a city. Cui starts
his trip from city s and his girl friend is in city t. As mentioned
above, Cui is so hurry that he will choose the quickest way to his girl
friend(in other words, he won't pass a city twice) and of course, buy as
many as gifts as possible. Now he wants to know, how much money does he
need to prepare for all the gifts?
 

Input

There are multiple cases.

For each case:
The first line contains tow integers n,m(1≤n,m≤10^5), representing the number of cities and the number of situations.
The second line contains n integers c1,c2,...,cn(1≤ci≤10^9), indicating the price of city i's specialty.
Then n-1 lines follows. Each line has two integers x,y(1≤x,y≤n), meaning there is road between city x and city y.
Next
m line follows. In each line there are four integers
s,t,a,b(1≤s,t≤n;1≤a≤b≤10^9), which indicates start city, end city, lower
bound of the price, upper bound of the price, respectively, as the
exact meaning mentioned in the description above

 

Output

Output m space-separated integers in one line, and the ith number should be the answer to the ith situation.
 

Sample Input

5 3
1 2 1 3 2
1 2
2 4
3 1
2 5
4 5 1 3
1 1 1 1
3 5 2 3

Sample Output

7 1 4
 

Source

 

题意

给你一棵树,每个点有点权,每次求一条路径点权大于等于a小于等于b的点权和,即求vi的和(a<=vi<=b)
 

题解

我在上次南昌网络赛遇到几乎一模一样的题,当时直接树链剖分+主席数过了,结果这次T了,而且这题数据暴力都能过,我还很不服气的拿暴力对拍,结果真的真的比暴力慢了三四倍吧,想哭了。
在这题上耗了两小时,终于选择向大佬低头,去看题解了,果然我还是太弱了。

以上来自以为蒟蒻的内心独白,接下来假装自己想出来的,讲波题解:
 
我们令sum(x)表示小于等于x的权值和,那么ans=sum(b)-sum(a-1)。当然对于每条路径,sum(x)都不一样,真的吗。
对于一条路径(l,r,a,b)先拆成两个路径,即(l,r,a-1,-1)和(l,r,b,1),并统称为(l,r,val,id),分别求答案,最后相减即可。
然后我们问题转化成了求路径小于等于val的权值和。
对两条路径(l1,r1,val1,id1) 和(l2,r2,val2,id2) ,如果val1<val2那么第一条路径的答案被第二条路径的答案包含。
接下来定义get_sum(u,v)为点u到v路径的权值和,一开始每个点都等于零。
这样不难想到将所有路径按val 从小到大排序,然后扫描路径数组,每次将树上节点权值小于等于val的所有点加上该点的权值,此路径的ans=get_sum(l,r)。
 

AC代码

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
#define INF 123456789
int n,m;
int tot,last[N];
ll ans[N];
int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
struct Query
{
int l,r,id; ll val;
bool operator <(const Query&b)const
{return val<b.val;}
}a[N],que[N<<];
struct Edge{int from,to,s;}edges[N<<];
struct Tree{int l,r;ll sum;}tr[N<<];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge(int x,int y)
{
edges[++tot]=Edge{x,y,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre)
{
fa[x]=pre;
dp[x]=dp[pre]+;
size[x]=;
son[x]=;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x);
size[x]+=size[e.to];
if (size[e.to]>size[son[x]])son[x]=e.to;
}
}
void dfs2(int x,int y)
{
rk[x]=++cnt;
kth[cnt]=x;
top[x]=y;
if (son[x]==)return;
dfs2(son[x],y);
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==fa[x]||e.to==son[x])continue;
dfs2(e.to,e.to);
}
}
void bt(int x,int l,int r)
{
tr[x].l=l; tr[x].r=r; tr[x].sum=;
if (l==r)return;
int mid=(l+r)>>;
bt(x<<,l,mid);
bt(x<<|,mid+,r);
}
void update(int x,int p,ll tt)
{
if (p<=tr[x].l&&tr[x].r<=p)
{
tr[x].sum+=tt;
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if (p<=mid)update(x<<,p,tt);
if (mid<p)update(x<<|,p,tt);
tr[x].sum=tr[x<<].sum+tr[x<<|].sum;
}
ll query(int x,int l,int r)
{
if (l<=tr[x].l&&tr[x].r<=r)
return tr[x].sum;
int mid=(tr[x].l+tr[x].r)>>; ll ans=;
if (l<=mid)ans+=query(x<<,l,r);
if (mid<r)ans+=query(x<<|,l,r);
return ans;
}
ll get_sum(int x,int y)
{
int fx=top[x],fy=top[y];ll ans=;
while(fx!=fy)
{
if (dp[fx]<dp[fy])swap(x,y),swap(fx,fy);
ans+=query(,rk[fx],rk[x]);
x=fa[fx]; fx=top[x];
}
if (dp[x]<dp[y])swap(x,y);
ans+=query(,rk[y],rk[x]);
return ans;
}
void work()
{
read(n); read(m);
for(int i=;i<=n;i++)read(a[i].val),a[i].id=i;
for(int i=;i<=n-;i++)
{
int x,y;
read(x); read(y);
AddEdge(x,y);
AddEdge(y,x);
}
int num=;
for(int i=;i<=m;i++)
{
int l,r,x,y;
read(l); read(r); read(x);read(y);
que[++num]=Query{l,r,-i,x-};
que[++num]=Query{l,r,i,y};
}
sort(a+,a+n+);
sort(que+,que+num+);
dfs1(,);
dfs2(,);
bt(,,n);
int ds=;
for(int i=;i<=num;i++)
{
while(ds<=n&&a[ds].val<=que[i].val)
{
update(,rk[a[ds].id],a[ds].val);
ds++;
}
ll sum=get_sum(que[i].l,que[i].r);
if (que[i].id<) ans[-que[i].id]-=sum;
else ans[que[i].id]+=sum;
}
printf("%lld",ans[]);
for(int i=;i<=m;i++)printf(" %lld",ans[i]);
printf("\n");
}
void clear()
{
tot=; cnt=;
memset(last,,sizeof(last));
memset(ans,,sizeof(ans));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
//freopen("my.out","w",stdout);
#endif
while()
{
clear();
work();
}
}

TLE代码(树链剖分+主席树)

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
#define INF 123456789
int n,m,w[N];ll b[N];
int tot,last[N];
int tree_num,root[N];
int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
struct Edge{int from,to,s;}edges[N<<];
struct Tree{int l,r,ls,rs;ll sum;}tr[];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge(int x,int y)
{
edges[++tot]=Edge{x,y,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre)
{
fa[x]=pre;
dp[x]=dp[pre]+;
size[x]=;
son[x]=;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x);
size[x]+=size[e.to];
if (size[e.to]>size[son[x]])son[x]=e.to;
}
}
void dfs2(int x,int y)
{
rk[x]=++cnt;
kth[cnt]=x;
top[x]=y;
if (son[x]==)return;
dfs2(son[x],y);
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==fa[x]||e.to==son[x])continue;
dfs2(e.to,e.to);
}
}
void bt(int &x,int l,int r)
{
x=++tree_num;
tr[x].l=l; tr[x].r=r; tr[x].sum=;
if (l==r)return;
int mid=(l+r)>>;
bt(tr[x].ls,l,mid);
bt(tr[x].rs,mid+,r);
}
void add(int &x,int last,int p)
{
x=++tree_num;
tr[x]=tr[last];
tr[x].sum+=b[p];
if (tr[x].l==tr[x].r)return;
int mid=(tr[x].l+tr[x].r)>>;
if(p<=mid)add(tr[x].ls,tr[last].ls,p);
else add(tr[x].rs,tr[last].rs,p);
}
ll ask(int x,int y,int p)
{
if (tr[x].r<=p)return tr[y].sum-tr[x].sum;
int mid=(tr[x].l+tr[x].r)>>;ll ans=;
if (<=mid)ans+=ask(tr[x].ls,tr[y].ls,p);
if (mid<p)ans+=ask(tr[x].rs,tr[y].rs,p);
return ans;
}
ll get_sum(int x,int y,int tt)
{
int fx=top[x],fy=top[y];ll ans=;
while(fx!=fy)
{
if (dp[fx]<dp[fy])swap(x,y),swap(fx,fy);
ans+=ask(root[rk[fx]-],root[rk[x]],tt);
x=fa[fx]; fx=top[x];
}
if (dp[x]<dp[y])swap(x,y);
ans+=ask(root[rk[y]-],root[rk[x]],tt);
return ans;
}
void work()
{
read(n); read(m);
int num=;
for(int i=;i<=n;i++)read(w[i]),b[++num]=w[i];
b[++num]=INF;
for(int i=;i<=n-;i++)
{
int x,y;
read(x); read(y);
AddEdge(x,y);
AddEdge(y,x);
}
sort(b+,b+num+);
num=unique(b+,b+num+)-b-;
dfs1(,);
dfs2(,);
bt(root[],,num);
for(int i=;i<=n;i++)
{
int tt=lower_bound(b+,b+num+,w[kth[i]])-b;
add(root[i],root[i-],tt);
}
for(int i=;i<=m;i++)
{
if (i>)printf(" ");
int x,y,l,r;
read(x); read(y); read(l); read(r);
l=lower_bound(b+,b+num+,l)-b-;
r=upper_bound(b+,b+num+,r)-b-;
ll ans=get_sum(x,y,r);
ans-=get_sum(x,y,l);
printf("%lld",ans);
}
printf("\n");
}
void clear()
{
tot=; cnt=; tree_num=;
memset(last,,sizeof(last));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
while()
{
clear();
work();
}
}

L - Ch’s gift HDU - 6162的更多相关文章

  1. 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  2. HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9

    /* HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9 题意: N节点的树,Q组询问 每次询问s,t两节 ...

  3. HDU 6162 Ch’s gift (树剖 + 离线线段树)

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  4. hdu6162 Ch’s gift

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6162 题目: Ch’s gift Time Limit: 6000/3000 MS (Java ...

  5. Ch’s gift

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Proble ...

  6. 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...

  7. 【HDU 6162】 Ch’s gift

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6162 [算法] 离线树剖 我们知道,u到v路径上权值为[A,B]的数的和 = u到v路径上权值小于 ...

  8. HDU 6162 Ch’s gift

    Mr. Cui is working off-campus and he misses his girl friend very much. After a whole night tossing a ...

  9. HDU 6162 Ch's gift(树链剖分+线段树)

    题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...

随机推荐

  1. Java-Maven-Runoob:Maven 自动化构建

    ylbtech-Java-Maven-Runoob:Maven 自动化构建 1.返回顶部 1. 自动化构建定义了这样一种场景: 在一个项目成功构建完成后,其相关的依赖工程即开始构建,这样可以保证其依赖 ...

  2. python开发面向对象基础:封装

    一,封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 1. 将变化隔离: 2. 便于使用: 3. 提高复用性: 4. 提高安全性: [封装原则] 1. 将不需要对外提供的内 ...

  3. Dev DateEdit控件格式设置

    设置日期显示格式: 设置三个属性(显示时.编辑时) dtPubDate.Properties.DisplayFormat.FormatString = "yyyy-MM-dd";  ...

  4. Dev TreeList基本用法

    public partial class treelist_shijian : DevExpress.XtraEditors.XtraForm      {          public treel ...

  5. java-虚拟机-索引

    底层 JVM之堆内存(年经代,老年代) Java内存泄露的理解与解决 内存溢出和内存泄漏的区别.产生原因以及解决方案 JVM内容梳理 Jvm的体系结构

  6. 微信小程序API登录凭证(code),获得的用户登录态拥有一定的时效性

    调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要依赖会话密钥完成. OBJECT参 ...

  7. [原创]JMeter初次使用总结

    引言 最近开发 java 后端项目,对外提供Restful API接口,完整功能开发现已完成. 目前通过单测(68%行覆盖率)已保证业务逻辑正确性,同时也尝试使用JMeter进行压力测试以保证并发性能 ...

  8. ___pInvalidArgHandler already defined in LIBCMTD.lib(invarg.obj)

    vs2013编译项目时出错,网上很多的解决方案全都是垃圾,根本不能用 不过也有不是垃圾的,就是下面这个: 关于采用静态链接编译生成EXE库函数重复定义问题 看了好多关于类似LIBCMT.lib(inv ...

  9. 关于python3 发送邮件

    一:发送文本信息 from email.mime.text import MIMEText from email.header import Header from smtplib import SM ...

  10. OK6410之tftp下载内核,nfs…

    原文地址:OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]作者:千山我独行 由于工作的平台也是嵌入式,差不多的平台,所以一直就没有把自己买过来的ok6410板子好好玩玩.以前一直都是 ...