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+\sum_{x=1}^{n} [a_x\in [l,r]]de_u-2\sum_{x=1}^{n}[a_x\in [l,r]]*de_{lca(x,u)}$$
式子的前两项可以利用前缀和比较方便的计算,问题是那个lca的深度和,考虑两个点的lca深度就是两个点到根路径交集长度,所以可以依次把满足条件的对应点 到根路径上的每个点 加上到父亲的边权,然后查询就是从一个点到根的权值和,这个可以用树链剖分+线段树实现
然后考虑询问一个\(a_i\)的\([l,r]\)区间答案,可以看成询问\([1,r]\)减去\([1,l-1]\)所以可以套一个主席树,注意主席树要区间修改,要实现标记永久化
#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register
using namespace std;
const int N=150000+10,mod=1e9+7;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
LL w[N<<1];
il void add(int x,int y,int z)
{
++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],w[tot]=z,hd[y]=tot;
}
int fa[N],fe[N],sz[N],hs[N],top[N],dfn[N],ti;
LL de[N],s1[N],s2[N],ans;
void dfs1(int x)
{
sz[x]=1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,fe[y]=i,de[y]=de[x]+w[i],dfs1(y),sz[x]+=sz[y];
hs[x]=sz[hs[x]]>sz[y]?hs[x]:y;
}
}
void dfs2(int x,int ntp)
{
dfn[x]=++ti,s1[ti]=s1[ti-1]+w[fe[x]],top[x]=ntp;
if(hs[x]) dfs2(hs[x],ntp);
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=fa[x]&&y!=hs[x]) dfs2(y,y);
}
}
int n,q,rt[N],tt,aa;
struct sd
{
int a,i;
bool operator < (const sd &bb) const {return a<bb.a;}
}mm[N];
struct node
{
int ch[2];
LL s,t;
}s[N*120];
#define mid ((l+r)>>1)
#define lc (s[o].ch[0])
#define rc (s[o].ch[1])
void bui(int &o,int l,int r)
{
o=++tt;
if(l==r) return;
bui(lc,l,mid),bui(rc,mid+1,r);
}
void modif(int &o,int l,int r,int ll,int rr)
{
s[++tt]=s[o],o=tt;
if(l==ll&&r==rr) {++s[o].t;return;}
s[o].s+=s1[rr]-s1[ll-1];
if(ll<=mid) modif(lc,l,mid,ll,min(mid,rr));
if(rr>mid) modif(rc,mid+1,r,max(mid+1,ll),rr);
}
LL quer(int o,int l,int r,int ll,int rr)
{
if(!o) return 0;
LL an=s[o].t*(s1[rr]-s1[ll-1]);
if(l==ll&&r==rr) return an+s[o].s;
if(ll<=mid) an+=quer(lc,l,mid,ll,min(mid,rr));
if(rr>mid) an+=quer(rc,mid+1,r,max(mid+1,ll),rr);
return an;
}
#undef mid
int main()
{
n=rd(),q=rd(),aa=rd();
bui(rt[0],1,n);
for(int i=1;i<=n;++i) mm[i]=(sd){rd(),i};
sort(mm+1,mm+n+1);
for(int i=1;i<n;++i)
{
int x=rd(),y=rd(),z=rd();
add(x,y,z);
}
dfs1(1),dfs2(1,1);
for(int i=1;i<=n;++i)
{
s2[i]=s2[i-1]+de[mm[i].i];
rt[i]=rt[i-1];
int x=mm[i].i;
while(x)
{
modif(rt[i],1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
}
while(q--)
{
int x=rd(),ll=(rd()+ans)%aa,rr=(rd()+ans)%aa;
if(ll>rr) swap(ll,rr);
int l=1,r=n,z=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(mm[mid].a>=ll) z=mid,r=mid-1;
else l=mid+1;
}
ll=z;
l=1,r=n,z=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(mm[mid].a<=rr) z=mid,l=mid+1;
else r=mid-1;
}
rr=z;
ans=1ll*(rr-ll+1)*de[x]+s2[rr]-s2[ll-1];
while(x)
{
ans-=2*(quer(rt[rr],1,n,dfn[top[x]],dfn[x])-quer(rt[ll-1],1,n,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
printf("%lld\n",ans);
}
return 0;
}
luogu P3241 [HNOI2015]开店的更多相关文章
- 洛谷 P3241 [HNOI2015]开店 解题报告
P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...
- P3241 [HNOI2015]开店 动态点分治
\(\color{#0066ff}{ 题目描述 }\) 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想 ...
- Luogu 3241 [HNOI2015]开店
BZOJ 4012权限题 浙科协的网突然炸了,好慌…… 据说正解是动态点分治,然而我并不会,我选择树链剖分 + 主席树维护. 设$dis_i$表示$i$到$root(1)$的值,那么对于一个询问$u$ ...
- 并不对劲的bzoj4012:loj2116:p3241: [HNOI2015]开店
题目大意 有一棵\(n\)(\(n\leq1.5*10^5\))个节点的二叉树,有点权\(x\),边权\(w\),\(q\)(\(q\leq2*10^5\))组询问,每组询问给出\(u,l,r\),求 ...
- luogu 3241 [HNOI2015]开店 动态点分治+二分+vector
独立写出来+想出来的,1.5h就切了~ 建立点分树,然后用 $vector$ 暴力存所有子节点,然后二分一下子就可以了. #include <cstdio> #include <ve ...
- P3241 [HNOI2015]开店
题解:动态点分治 建立点分树 每个点维护点分树子树内节点到这个节点和父亲节点距离的前缀和 二分查找锁定合法区间 对每个祖先分治中心查询路径和然后减去不合法子树内的路径和 注意:求大量LCA时用树剖 不 ...
- LOJ #2116 Luogu P3241「HNOI2015」开店
好久没写数据结构了 来补一发 果然写的时候思路极其混乱.... LOJ #2116 Luogu P3241 题意 $ Q$次询问,求树上点的颜色在$ [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] ...
随机推荐
- python面向对象编程 -- 基本概念
面向对象的编程简要概括就是将要处理的问题抽象为数据和操作的集合,用类对其进行封装.其中数据和操作都称为类的属性,它们是一般是不变的. 对类进行实例化生成我们所说的对象,对象有自己的属性.对象的属性一般 ...
- [luogu3709][大爷的字符串题]
题目链接 题意 一天做到两道这种题目描述如此神仙的题也是够了.真锻炼语文能力. 题目的意思其实就是,给你一个序列,然后每次询问一个区间.使得尽量按照严格上升的顺序从这个区间内取数.如果当前取得数字小于 ...
- [luogu3377][左偏树(可并堆)]
题目链接 思路 左偏树的模板题,参考左偏树学习笔记 对于这道题我是用一个并查集维护出了哪些点是在同一棵树上,也可以直接log的往上跳寻找根节点 代码 #include<cstdio> #i ...
- (转)git stash使用
使用情形 综合下网上的介绍和资料,git stash(git储藏)可用于以下情形: 发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交.这时就可以考虑git s ...
- django2用模板代码图标字体丢失报404 cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff
以前开发网站,不是用php就是用c#或java写后端,跟后端繁重麻烦的代码相比,前端的html+css+JavaScript简直就简单的不算技术,相比之下,工作量也不大. 但如果用django框架,使 ...
- golang与vscode的安装与配置
一.golang的下载与安装 以下都是win10的安装与配置 go语言官方下载地址:https://golang.org/dl/ 找到适合你系统的版本下载 傻瓜式安装开始... 二.golang环境变 ...
- javase的网络编程(InetAddress,UDP,TCP,URL,Socket,DatagramSocket)
通过一段时间对java网络编程相关内容的学习,写下这篇随笔,对这一部分的知识进行梳理和总结. 网络编程 一.网络编程三要素: IP地址:网络会给每个联网的主机分配一个数字的编码地址,该地址就是IP地址 ...
- Good Bye 2018 B. New Year and the Treasure Geolocation
传送门 https://www.cnblogs.com/violet-acmer/p/10201535.html 题意: 在二维空间中有 n 个 obelisk 点,n 个 p 点: 存在坐标T(x, ...
- js怎么获取微信浏览器内容的高度
通过window对象来得到窗口相关的内外款高度信息,如下: outerHeight属性设置或返回一个窗口的外部高度,包括所有界面元素(如工具栏/滚动条).outerWidth属性设置或返回窗口的外部宽 ...
- glob.glob 匹配文件
glob.glob以列表形式返回匹配的文件路径 只有一个参数:文件的匹配规则 e.g. >>>res_home = '/vip_data_center/test_envs/train ...