P3241 [HNOI2015]开店
题解:动态点分治
建立点分树
每个点维护点分树子树内节点到这个节点和父亲节点距离的前缀和
二分查找锁定合法区间
对每个祖先分治中心查询路径和然后减去不合法子树内的路径和
注意:求大量LCA时用树剖
不开O2时少用STL
相乘炸int
lower_bound和upper_bound返回值边界
注意常数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=200009;
const int oo=1000000000;
typedef long long Lint; int n,T,u;
int a[maxn]; int cntedge;
int head[maxn];
int to[maxn<<1],nex[maxn<<1],dist[maxn<<1];
void Addedge(int x,int y,int z){
nex[++cntedge]=head[x];
to[cntedge]=y;
dist[cntedge]=z;
head[x]=cntedge;
} int nowsiz,root;
int vis[maxn];
int siz[maxn],g[maxn];
void Getsiz(int x,int fa){
siz[x]=1;
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
if(to[i]==fa)continue;
Getsiz(to[i],x);
siz[x]+=siz[to[i]];
}
}
void Getroot(int x,int fa){
siz[x]=1;
g[x]=0;
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
if(to[i]==fa)continue;
Getroot(to[i],x);
siz[x]+=siz[to[i]];
g[x]=max(g[x],siz[to[i]]);
}
g[x]=max(g[x],nowsiz-siz[x]);
if(g[x]<g[root])root=x;
} int divfa[maxn];
void Sol(int x){
vis[x]=1;
Getsiz(x,0);
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
root=0;nowsiz=siz[to[i]];
Getroot(to[i],x);
divfa[root]=x;
Sol(root);
}
} int father[maxn],dep[maxn],d[maxn],top[maxn],hson[maxn];
void Dfs(int x,int fa){
father[x]=fa;
dep[x]=dep[fa]+1;
siz[x]=1;
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
d[to[i]]=d[x]+dist[i];
Dfs(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[hson[x]])hson[x]=to[i];
}
}
void Dfs2(int x,int toppoint){
top[x]=toppoint;
if(!hson[x])return;
Dfs2(hson[x],toppoint);
for(int i=head[x];i;i=nex[i]){
if(to[i]==father[x])continue;
if(to[i]==hson[x])continue;
Dfs2(to[i],to[i]);
}
} int Getlca(int u,int v){
int tu=top[u];
int tv=top[v];
while(tu!=tv){
if(dep[tu]<dep[tv]){
swap(u,v);
swap(tu,tv);
}
u=father[tu];
tu=top[u];
}
if(dep[u]<dep[v])return u;
else return v;
} int Getdist(int x,int y){
if((x==0)||(y==0))return 0;
int lca=Getlca(x,y);
return d[x]+d[y]-d[lca]-d[lca];
} vector<int>G[maxn];
vector<Lint>S[maxn];
vector<Lint>S2[maxn]; int cmp(const int &rhs1,const int &rhs2){
return a[rhs1]<a[rhs2];
} int main(){
scanf("%d%d%d",&n,&T,&u);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<n;++i){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Addedge(x,y,z);
Addedge(y,x,z);
} Dfs(1,0);
Dfs2(1,1); g[0]=oo;root=0;nowsiz=n;
Getroot(1,0);
Sol(root); for(int i=1;i<=n;++i){
int x=i;
while(x){
G[x].push_back(i);
x=divfa[x];
}
} // for(int i=1;i<=n;++i){
// for(int j=1;j<=n;++j){
// cout<<Getdist(i,j)<<' ';
// }
// cout<<endl;
// }
for(int i=1;i<=n;++i){
sort(G[i].begin(),G[i].end(),cmp);
Lint now=0,now2=0;
for(int j=0;j<G[i].size();++j){
now=now+Getdist(i,G[i][j]);
now2=now2+Getdist(divfa[i],G[i][j]);
S[i].push_back(now);
S2[i].push_back(now2);
G[i][j]=a[G[i][j]];
}
// printf("=->%d %d %d\n",i,now,now2);
}
// for(int i=1;i<=n;++i)cout<<d[i]<<' ';
// cout<<endl;
Lint ans=0;
while(T--){
int x,y,Lold,Rold;
scanf("%d%d%d",&x,&Lold,&Rold);
y=x;
int t1=(Lold+ans)%u;
int t2=(Rold+ans)%u;
Lold=min(t1,t2);
Rold=max(t1,t2);
// cout<<Lold<<' '<<Rold<<endl;
ans=0;
int p=0;
// cout<<ans<<endl;
// for(int i=0;i<G[x].size();++i)cout<<G[x][i]<<' ';
// cout<<endl;
p=upper_bound(G[x].begin(),G[x].end(),Rold)-G[x].begin()-1;
if(p>-1)ans+=S[x][p];
// cout<<p<<endl;
p=lower_bound(G[x].begin(),G[x].end(),Lold)-G[x].begin();
if(p)ans-=S[x][p-1];
// cout<<p<<endl;
// cout<<ans<<endl;
while(divfa[x]){
Lint fdist=Getdist(divfa[x],y);
int fa=divfa[x]; p=upper_bound(G[fa].begin(),G[fa].end(),Rold)-G[fa].begin()-1;
if(p>-1)ans+=S[fa][p]+fdist*(p+1);
// cout<<p<<' ';
p=lower_bound(G[fa].begin(),G[fa].end(),Lold)-G[fa].begin();
if(p)ans-=S[fa][p-1]+fdist*p;
// cout<<p<<endl;
// cout<<ans<<endl;
p=upper_bound(G[x].begin(),G[x].end(),Rold)-G[x].begin()-1;
if(p>-1)ans-=S2[x][p]+fdist*(p+1);
p=lower_bound(G[x].begin(),G[x].end(),Lold)-G[x].begin();
if(p)ans+=S2[x][p-1]+fdist*p;
// cout<<ans<<endl;
x=divfa[x];
}
printf("%lld\n",ans);
}
return 0;
}
P3241 [HNOI2015]开店的更多相关文章
- 洛谷 P3241 [HNOI2015]开店 解题报告
P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...
- P3241 [HNOI2015]开店 动态点分治
\(\color{#0066ff}{ 题目描述 }\) 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想 ...
- luogu P3241 [HNOI2015]开店
传送门 (下面记年龄为\(a_x\))题目要求的是\[\sum_{x=1}^{n} [a_x\in [l,r]]*dis(x,u)=\sum_{x=1}^{n} [a_x\in [l,r]]*de_x ...
- 并不对劲的bzoj4012:loj2116:p3241: [HNOI2015]开店
题目大意 有一棵\(n\)(\(n\leq1.5*10^5\))个节点的二叉树,有点权\(x\),边权\(w\),\(q\)(\(q\leq2*10^5\))组询问,每组询问给出\(u,l,r\),求 ...
- [HNOI2015]开店 树链剖分,主席树
[HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...
- [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)
4012: [HNOI2015]开店 Time Limit: 70 Sec Memory Limit: 512 MBSubmit: 2168 Solved: 947[Submit][Status] ...
- 【BZOJ4012】[HNOI2015]开店 动态树分治+二分
[BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...
- BZOJ4012 [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- bzoj 4012: [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
随机推荐
- Day6-T3
原题目 某个帝国修了一条非常非常长的城墙来抵御外敌,城墙共分N段,每一段用一个整数来描述坚固程度. 过了几年,城墙年久失修,有很多段都己经损坏,于是皇帝决定派你去修理城墙,但是经费有限. 所以你准备先 ...
- ROS常用库(三)API学习之常用common_msgs(上)
一.概述 common_msgs包含其他ROS软件包广泛使用的消息.这些消息包括动作消息(actionlib_msgs),诊断消息(diagnostic_msgs),几何图元(geometry_msg ...
- Android的事件处理机制之基于回调的事件处理
回调机制 如果说事件监听机制是一种委托式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,换种方法说事件监听器完全消失了,当用户在GUI组件上激发某个事件 ...
- loadBeanDefinitions方法源码跟踪(三)
因为字数超过了限制,所以分成了三篇,承接上篇: https://www.jianshu.com/p/46e27afd7d96 代码过宽,可以shift + 鼠标滚轮 左右滑动查看 4.parseCus ...
- Ceph 概念理解
简介 Ceph是一个可靠地.自动重均衡.自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储.块设备存储和文件系统服务. 在虚拟化领域里,比较常用到的是Ceph的块设备存储, ...
- 浅析Java NIO
浅析Java NIO 前言 在说NIO之前,先来说说IO的读写原理.我们都知道Java中的IO流可以分为网络IO流和文件IO流,前者在网络中使用,后者在操作文件时使用.但实际上两种流区别并不是太大 ...
- 2的n次幂
位运算判断2的n次幂: 举个栗子,n = 8:则二进制表示就为1000,n-1则为 0111 取&刚好等于0 嘿嘿,巧妙吧. 再举个栗子,n = 7: 则二进制为 0111,n-1则为0110 ...
- mysql更新某一列数据
UPDATE 表名 SET 字段名 = REPLACE(替换前的字段值, '替换前关键字', '替换后关键字'); select * from province; +----+------------ ...
- Windows 下 GNS3 安装与基本使用指南
1.GNS3简介 GNS3是一款图形化的网络虚拟软件,可以运行在多个平台(windows,linux,mac OS).我们可以通过它来学习Cisco的认证,或者是检验将要在生产环境中部署实施的相关配置 ...
- JD-Store购物网站复盘——20170312
一.商店技术架构 1.主题 2.涉及技术点: 3.核心业务功能 4.角色 5.用户故事 二.实现步骤 专案基础设施 上传图片模块 购物车 订单 支付&寄信 专案源码 三.第三方服务应用 支付 ...