题目大意:

给你一棵树,边有边权,点有点权,有很多次询问,求点权$\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. iframe嵌入的子页面如何刷新父窗口

    iframe中刷新父页面方法及一些按钮刷新代码集合[原创+转]2009-07-23 11:12a页面里iframe了个b页面,我想实现在b页面里一个按钮,一按就刷新a页面,也就是父页面,不是只刷新if ...

  2. [poj 3666] Making the Grade (离散化 线性dp)

    今天的第一题(/ω\)! Description A straight dirt road connects two fields on FJ's farm, but it changes eleva ...

  3. Zookeeper分布式锁解决方案具体代码

    定义一个公共资源订单生成类: package com.itmayiedu.lock; import java.text.SimpleDateFormat; import java.util.Date; ...

  4. node+express框架中连接使用mysql经验总结

    最近在学习node.js,做了一个练手项目,使用node.js+express框架,配合mysql数据库和前端vue框架开发一个多人文档编辑系统. koa,express,node 通用方法连接MyS ...

  5. Redis 报错:MISCONF Redis is configured to save RDB snapshots

    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Com ...

  6. Python中的全局变量与局部变量的区别

    全局变量与局部变量两者的本质区别就是在于作用域 用通俗的话来理解的话, 全局变量是在整个py文件中声明,全局范围内都可以访问 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地 ...

  7. 【codeforces 807C】Success Rate

    [题目链接]:http://codeforces.com/contest/807/problem/C [题意] 给你4个数字 x y p q 要求让你求最小的非负整数b; 使得 (x+a)/(y+b) ...

  8. Elasticsearch---基于scroll技术滚动搜索大量数据

    如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完 使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以 ...

  9. 洛谷—— P1220 关路灯

    https://www.luogu.org/problem/show?pid=1220 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住 ...

  10. crm使用soap批量删除数据

    //批量删除数据 function demo() {     //实体名称     var entityname = "fw_student";     var data = [] ...