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. PHP实现四种基本排序算法 得多消化消化

    1.冒泡排序 // 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序 ...

  2. 《转载》ubuntu Sublime text 3 解决中文输入问题

    其实,在这个文章之前,网上都有好多教程了.不知道是不是因为复制黏贴的传播太多,导致有些字符串的丢失,导致编译失败,so库文件无法载入,从而不能输入中文.折腾了许久之后,终于搞定了.记录下来,方便自己下 ...

  3. MFC学习(一) MFC基础类及其层次结构

    从类CCmdTarget派生出绝大多数MFC中的类,其层次结构如下图: 从根类Cobject层层派生出绝大多数MFC中的类,层次结构如下图: MFC中重点类: CObject类是MFC的绝大部分类的基 ...

  4. a标签什么时候可以设置宽高

    行内元素(如a标签),在文档流中的时候因为是行内元素所以无法设置宽高:而当设置了绝对定位或者浮动,会生成块框(即变成块元素),所以就可以设置宽高了

  5. msf上MS-2017-010(Eternalblue)的复现

    目标主机:192.168.220.148,系统为Microsoft Windows Server 2008 R2 Datacenter,开启了445端口 开启msf root@sch01ar:~# m ...

  6. Django模板语言之组合搜索

    url.py from django.conf.urls import url from django.contrib import admin from app01 import views url ...

  7. A Look at the Razor View Engine in ASP.NET MVC

    The biggest architectural difference that exists between ASP.NET MVC and ASP.NET Web Forms is the ne ...

  8. GCC 常见参数配置

    博客转载自:https://www.cnblogs.com/zhangsir6/articles/2956798.html 简介gcc and g++现在是gnu中最主要和最流行的c & c+ ...

  9. oracle高级查询练习题

    1.  列出员工表中每个部门的员工数和部门编号 Select deptno,count(*) from emp group by deptno; 补充1:列出员工表中,员工人数大于3的部门编号和员工人 ...

  10. win32多线程(三) 死锁

    任何时候当一段代码需要两个(或更多)资源时,都有潜在性的死锁. void SwapLists(List *list1, List *list2) { List *tmp_list; EnterCrit ...