题目大意:

给你一棵树,边有边权,点有点权,有很多次询问,求点权$\in[l,r]$的所有节点到某点$x$的距离之和,强制在线

感觉这个题应该放在动态点分之前做= =

套路方法和动态点分是一样的

每次询问,从$x$开始,沿着点分树的树链向上统计,计算当前点的点分树的答案,然后去掉包含$x$的那棵点分子树的答案

$x$节点在点分树内的 所有祖先节点 对于答案的贡献都有两个部分

1.除了包含$x$的点分子树 的所有权值$\in[l,r]$的节点到 当前祖先节点 的距离

2.合法节点数量*当前祖先节点到$x$的距离

而这道题是静态的,不用每个节点都开线段树,改成$vector$,每次都在上面二分就好了

具体实现

每个节点都开一个$vector$,设当前的点分节点是$x$,把$x$点分树内的所有子节点推进去,按照点权排序,再统计一下到$x$距离的前缀和

统计$[l,r]$的答案时,只需要在$vector$里二分出右端点查询dis的前缀和,还要加上点数总和(即右端点下标) *当前 点分树节点 到 询问节点 的距离,再利用前缀和容斥$calc(r)-calc(l-1)$即可

时间仍然是$O(nlog^{2}n)$,但空间变成了$O(nlogn)$

由于用了$vector$常数大的一批但我也懒得优化了

 #include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 150100
#define ll long long
#define dd double
#define inf 0x3f3f3f3f3f3f3f3fll
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} struct Edge{
int to[N1<<],nxt[N1<<],val[N1<<],head[N1],cte;
void ae(int u,int v,int w){
cte++;to[cte]=v;val[cte]=w;
nxt[cte]=head[u];head[u]=cte;}
}e;
namespace tr{
ll dis[N1];int dep[N1],ff[N1<<][],lg[N1<<],st[N1<<],tot;
void dfs1(int u,int dad)
{
st[u]=++tot; ff[tot][]=u;
for(int j=e.head[u];j;j=e.nxt[j])
{
int v=e.to[j]; if(v==dad) continue;
dis[v]=dis[u]+e.val[j]; dep[v]=dep[u]+;
dfs1(v,u); ff[++tot][]=u;
}
}
void get_st()
{
int i,j;
for(lg[]=,i=;i<=tot;i++) lg[i]=lg[i>>]+;
for(j=;j<=lg[tot];j++)
for(i=;i+(<<j)-<=tot;i++)
ff[i][j]=dep[ ff[i][j-] ] < dep[ ff[i+(<<(j-))][j-] ] ? ff[i][j-] : ff[i+(<<(j-))][j-];
}
ll Dis(int x,int y)
{
int tx=min(st[x],st[y]),ty=max(st[x],st[y]),L=ty-tx+;
int fa=dep[ ff[tx][lg[L]] ] < dep[ ff[ty-(<<lg[L])+][lg[L]] ] ? ff[tx][lg[L]] : ff[ty-(<<lg[L])+][lg[L]];
return dis[x]+dis[y]-2ll*dis[fa];
}
void init(){dfs1(,-);get_st();}
};
int n,m,ma;
int ms[N1],sz[N1],use[N1],fr[N1],fa[N1],a[N1],tsz,G;
void gra(int u,int dad)
{
sz[u]=; ms[u]=;
for(int j=e.head[u];j;j=e.nxt[j])
{
int v=e.to[j]; if(v==dad||use[v]) continue;
gra(v,u);
sz[u]+=sz[v]; ms[u]=max(ms[u],sz[v]);
}
ms[u]=max(ms[u],tsz-sz[u]);
if(ms[u]<ms[G]) G=u;
}
int que[N1],hd,tl;
ll dis[N1];
struct node{int id;ll sum;};
vector<node>rm[N1],rf[N1];
int cmp(node x,node y){return a[x.id]<a[y.id];}
void bfs_add(int u,int g)
{
int j,v; hd=tl=; que[hd]=u; fr[u]=; dis[u]=;
while(hd<=tl)
{
u=que[hd++]; rm[g].push_back((node){u,dis[u]});
for(j=e.head[u];j;j=e.nxt[j])
{
v=e.to[j]; if(use[v]||v==fr[u]) continue;
fr[v]=u; dis[v]=dis[u]+e.val[j];
que[++tl]=v;
}
}
sort(rm[g].begin(),rm[g].end(),cmp);
for(j=;j<rm[g].size();j++)
rm[g][j].sum+=rm[g][j-].sum;
}
void bfs_sub(int u,int g)
{
int j,v; hd=tl=; que[hd]=u;
while(hd<=tl)
{
u=que[hd++]; rf[g].push_back((node){u,dis[u]});
for(j=e.head[u];j;j=e.nxt[j])
{
v=e.to[j]; if(use[v]||v==fr[u]) continue;
que[++tl]=v;
}
}
sort(rf[g].begin(),rf[g].end(),cmp);
for(j=;j<rf[g].size();j++)
rf[g][j].sum+=rf[g][j-].sum;
}
void main_dfs(int u)
{
use[u]=; bfs_add(u,u);
for(int j=e.head[u];j;j=e.nxt[j])
{
int v=e.to[j]; if(use[v]) continue;
G=; tsz=sz[v]; gra(v,-); bfs_sub(v,G); fa[G]=u;
main_dfs(G);
}
}
using tr::Dis;
ll calc(vector<node>&s,int lim,int &sum,int type)
{
int l=,r=s.size()-,mid,ans=-;
while(l<=r)
{
mid=(l+r)>>;
if(a[s[mid].id]<=lim) l=mid+,ans=mid;
else r=mid-;
}
if(ans==-) return ;
sum+=type*(ans+);
return s[ans].sum;
}
ll solve(int x,int L,int R)
{
ll ans=;int sum;
for(int i=x;i;i=fa[i])
{
sum=;
ans+=calc(rm[i],R,sum,)-calc(rm[i],L-,sum,-);
ans+=sum*Dis(x,i);
if(!fa[i]) continue;
sum=;
ans-=calc(rf[i],R,sum,)-calc(rf[i],L-,sum,-);
ans-=sum*Dis(x,fa[i]);
}
return ans;
} int main()
{
scanf("%d%d%d",&n,&m,&ma);
int i,j,x,y,w,A,B,l,r;ll ans=;
for(i=;i<=n;i++) a[i]=gint();
for(i=;i<n;i++) x=gint(), y=gint(), w=gint(), e.ae(x,y,w), e.ae(y,x,w);
tr::init();
tsz=ms[]=n; G=; gra(,-); gra(G,-);
main_dfs(G);
for(j=;j<=m;j++)
{
x=gint(); A=gint(); B=gint();
l=(ans+A)%ma; r=(ans+B)%ma; if(l>r) swap(l,r);
ans=solve(x,l,r);
printf("%lld\n",ans);
}
return ;
}

BZOJ 4012 [HNOI2015]开店 (树分治+二分)的更多相关文章

  1. BZOJ 4012 HNOI2015 开店 树的边分治+分治树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 题意概述:给出一颗N点的树,保证树上所有点的度不超过3,树上每个点有权值,每条边有权 ...

  2. bzoj 4012: [HNOI2015]开店 主席树

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  3. BZOJ 4012 [HNOI2015]开店 (区间修改 永久化标记 主席树)

    讲得好啊 主席树区间修改了,每一次遇到整区间就打永久化标记(不下传,访问的时候沿路径上的标记算答案)然后returnreturnreturn,那么每修改一次只会访问到lognlognlogn个节点,再 ...

  4. bzoj 4012: [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  5. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  6. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  7. 【BZOJ4012】[HNOI2015]开店 动态树分治+二分

    [BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...

  8. 【BZOJ】4012: [HNOI2015]开店

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 给出一个$n$个点的树,树上每一个点都有一个值$age$,每条边都有边权,每次查询一 ...

  9. Gym - 101002K:YATP (树分治+二分+斜率优化)

    题意:给定带点权边权的树,定义路径的花费=路径边权和e+起点点权w[s]*终点点权w[t].N<2e5,e,w<1e6: 思路:首先,需要树分治. 然后得到方程dp[i]=min{ dis ...

随机推荐

  1. 主题:实战WebService II: SOAP篇(基于php)

    概述(SOAP和XML-PRC比较) 在Web服务发展的初期,XML格式化消息的第一个主要用途是,应用于XML-RPC协议,其中RPC代表远程过程调用.在XML远程过程调用 (XML-RPC)中,客户 ...

  2. Linux 基础入门一

    操作系统1.简介OS: Operating System,通用目的的软件程序操作系统的内核(kernel):  操作系统其实也是一组程序.这组程序的重点在于管理计算机的所有活动及驱动系统中的所有硬件: ...

  3. 《黑白团团队》第八次团队作业:Alpha冲刺 第四天

    项目 内容 作业课程地址 任课教师首页链接 作业要求 团队项目 填写团队名称 黑白团团队 填写具体目标 认真负责,完成项目 团队项目Github仓库地址链接. 第四天 日期:2019/6/18 成员 ...

  4. Java基础学习总结(64)——Java内存管理

    本文介绍的Java虚拟机(JVM)的自动内存管理机制主要是参照<深入理解Java虚拟机>(第2版)一书中的内容,主要分为两个部分:Java内存区域和内存溢出异常.垃圾回收和内存分配策略.因 ...

  5. redis 对 key 的操作

    keys * :查询当前库中所有的 key keys k? :问号是占位符 del key :删除指定的 key exists k1 :判断 k1 是否存在 move k1 2  :(剪切) 将 k1 ...

  6. 16 个 Linux 服务器监控命令

    如果你想知道你的服务器正在做干什么,你就需要了解一些基本的命令,一旦你精通了这些命令,那你就是一个 专业的 Linux 系统管理员. 有些 Linux 发行版会提供 GUI 程序来进行系统的监控,例如 ...

  7. js 文档加载完成之后执行 备用

    //文档加载完成之后执行 (function(){ var _globeCallback; window.$$ = function(callback){ _globeCallback = callb ...

  8. opencv3.2+opencv_contrib+cmake

    转自原文 opencv3.2+opencv_contrib+cmake 心得体会 初学OpenCV发现opencv3.2(下载链接在附录)是没有xfeatures2d等模块的.第三方库opencv_c ...

  9. 面试宝典之基本的C#面试问答

    下文是100个基本的C#面试问答清单.这些面试问题简单.直接了当,涵盖了C#最基本的概念,大部分和面向对象的概念相关.所以如果你在准备C#面试,我建议你必须掌握这100个基本的C#面试问答来复习你的C ...

  10. 韩国IT业是怎么走向国际我们须要学习什么

    无论从国土面积仍是从人口数量上来衡量.韩国都不能算是一个大国,而且自然资本十分缺乏,即是在这种情况下,韩国经过几十年的尽力开展变成技能大国,格外是在IT这种新经济范畴更是引人注目.并诞生了三星等国际级 ...