HDU 6162 Ch’s gift (树剖 + 离线线段树)
Ch’s gift
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 662 Accepted Submission(s): 229
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?
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
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
【题意】给你一棵树,每个节点有一个权值,M次询问,给出u,v,a,b,求权值在区间[a,b]中的和。
【分析】数据实在是太水了,暴力都能过,这里说一下正确的树剖,离线往线段树插值得写法。将每个询问分成两部分,[1,b]-[1,a-1],放进一个 集合排序,从小到大取出,将节点权值同样 排序,若当前权值<=询问中的权值,则插入线段树。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e5+;;
const int M = ;
const int mod = ;
const int mo=;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N];
int num,n,m;
ll ans[N];
vector<int>edg[N];
vector<pii>vec;
struct query{
int u,v,x,id;
bool operator <(const query &d)const{
return x<d.x;
}
}q[N*];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int v : edg[u]) {
if (v == f) continue;
dfs1(v, u, d + );
siz[u] += siz[v];
if (siz[son[u]] < siz[v])
son[u] = v;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int v : edg[u]) {
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
} struct Tree {
int l,r;
ll sum;
};
Tree tree[*N];
void pushup(int x) {
tree[x].sum=tree[lson(x)].sum+tree[rson(x)].sum;
}
void build(int l,int r,int v) {
tree[v].l=l;
tree[v].r=r;
if(l==r) {
tree[v].sum=;
return ;
}
int mid=(l+r)>>;
build(l,mid,v*);
build(mid+,r,v*+);
pushup(v);
}
void update(int o,int v,int val) {
if(tree[o].l==tree[o].r) {
tree[o].sum= val;
return ;
}
int mid = (tree[o].l+tree[o].r)/;
if(v<=mid)
update(o*,v,val);
else
update(o*+,v,val);
pushup(o);
}
ll querySum(int x,int l,int r) {
if (tree[x].l >= l && tree[x].r <= r) {
return tree[x].sum;
}
int mid = (tree[x].l + tree[x].r) / ;
ll ans = ;
if (l <= mid) ans += querySum(lson(x),l,r);
if (r > mid) ans += querySum(rson(x),l,r);
return ans;
}
ll Qsum(int u,int v) {
int tp1 = top[u], tp2 = top[v];
ll ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans +=querySum(,id[tp1], id[u]);
u = fa[tp1];
tp1 = top[u];
}
if (dep[u] > dep[v])swap(u, v);
ans +=querySum(,id[u], id[v]);
return ans;
}
void init(){
for(int i=;i<N;i++)edg[i].clear();
met(tree,);met(son,);vec.clear();met(ans,);
}
int main() {
while(~scanf("%d%d",&n,&m)) {
init();
for(int i=,x; i<=n; i++)scanf("%d",&x),vec.pb(mp(x,i));
for(int i=,u,v; i<n; i++) {
scanf("%d%d",&u,&v);
edg[u].pb(v);edg[v].pb(u);
}
num = ;
dfs1(,,);
dfs2(,);
sort(vec.begin(),vec.end());
for(int i=;i<=m;i++){
int x,y,a,b;
scanf("%d%d%d%d",&x,&y,&a,&b);
q[i]=query{x,y,a-,-i};
q[i+m]=query{x,y,b,i};
}
sort(q+,q+*m+);
int now=;
build(,num,);
for(int i=;i<=*m;i++){
while(now<n&&vec[now].first<=q[i].x){
update(,id[vec[now].second],vec[now].first);
now++;
}
ans[abs(q[i].id)]+=Qsum(q[i].u,q[i].v)*(q[i].id>?:-);
}
for(int i=;i<=m;i++)printf("%lld%c",ans[i],i==m?'\n':' ');
}
return ;
}
HDU 6162 Ch’s gift (树剖 + 离线线段树)的更多相关文章
- BZOJ 3626 [LNOI2014]LCA 树剖+(离线+线段树 // 在线+主席树)
BZOJ 4012 [HNOI2015]开店 的弱化版,离线了,而且没有边权(长度). 两种做法 1 树剖+离线+线段树 这道题求的是一个点zzz与[l,r][l,r][l,r]内所有点的lcalca ...
- 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两节 ...
- 【小技巧】树剖套线段树优化建图如何做到 O(nlogn)
前提:用树剖套线段树优化树链连边.例题:bzoj4699 我们说树剖的时间复杂度是 $O(n\times log(n))$,是因为访问一条链时需要经过 $log(n)$ 级别条重链,对于每条重链还需要 ...
- 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 ...
- 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...
- 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 ...
- HDU 6162 Ch’s gift (线段树+树链剖分)
题意:给定上一棵树,每个树的结点有一个权值,有 m 个询问,每次询问 s, t , a, b,问你从 s 到 t 这条路上,权值在 a 和 b 之间的和.(闭区间). 析:很明显的树链剖分,但是要用 ...
- HDU 6162 Ch's gift(树链剖分+线段树)
题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...
- BZOJ 3626: [LNOI2014]LCA(树剖+差分+线段树)
传送门 解题思路 比较有意思的一道题.首先要把求\(\sum\limits_{i=l}^r dep[lca(i,z)]\)这个公式变一下.就是考虑每一个点的贡献,做出贡献的点一定在\(z\)到根节点的 ...
随机推荐
- [洛谷P3763] [TJOI2017]DNA
洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...
- vs 统计有效代码行数
1.Visual Studio中,crtl+Shift+F,输入b*[^:b#/]+.*$ ,查找范围:选择整个解决方案,查找选项:使用正则表达式,文件类型:*.cs;*.cshtml 选择查找全部
- zk-web
Ref:https://github.com/qiuxiafei/zk-web zk-web是一个用clojure with noir and boostrap写的Zookeeper WEB UI管理 ...
- 【BZOJ4069】【APIO2015】巴厘岛的雕塑 [贪心][DP]
巴厘岛的雕塑 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description 印尼巴厘岛的公路上有许多的雕塑, ...
- 【BZOJ】2055 80人环游世界
[算法]有源汇上下界最小费用可行流 [题解]上下界 因为上下界相同,所以无所谓最小流了,可行流(初始流+附加流)就是答案了. 记得源点向新建节点连一条容量为m(人)的边. bzoj 2055 80人环 ...
- Ubuntu终端里面显示路径名称太长,怎么设置变短【转】
转自:http://blog.csdn.net/id19870510/article/details/8276914 $: sudo vi ~/.bashrc 这个文件记录了用户终端配置 找到 if ...
- caffe Python API 之卷积层(Convolution)
1.Convolution层: 就是卷积层,是卷积神经网络(CNN)的核心层. 层类型:Convolution lr_mult: 学习率的系数,最终的学习率是这个数乘以solver.prototxt配 ...
- CDN网站加速技术
什么是CDN? CDN(Content Delivery Network 内容分发网络)技术通过在各个地区部署缓存节点加速用户对静态资源的获取速度,提升用户体验,降低运营成本.CDN公司有网宿(Chi ...
- ubuntu下ssh服务相关操作
1.安装ssh服务:apt-get install openssh-server 2.检测ssh开启状态:ps -e | grep ssh 3.启动ssh:/etc/init.d/ssh start ...
- mysql大法
mysql大法 MySQL 安装方式 1.rpm(yum) 2.源码包 3.通用二进制 企业中版本选择 5.6 5.7 选择 GA 6个月到1年之间的------------------------- ...