题目链接:开店

  这道题显然一眼树分治,维护点分的结构,在每个点上,对每种年龄到这个点\(u\)以及他在点分树上父亲的距离和建一棵线段树,查询的时候一路往上跳即可。

  但是我太懒了(其实你要说我不会也可以),所以并不想写这种东西。于是,我就只能尝试一下别的方法。

  设一个点\(u\)的年龄为\(y_u\),\(u\)、\(v\)两点之间的距离为\(dis(u,v)\),\(T_u=dis(root,u)\),我们每次要求的式子是:

\begin{aligned} &\sum_{y_x\in [l,r]} dis(x,u)\\ =&\sum_{y_x\in [l,r]}(T_x+T_u-2T_{LCA(u,x)})\end{aligned}

  注意到前面那两项我们是可以通过预处理前缀和\(O(1)\)求出的。于是我们就只需要考虑后面那坨东西怎么求。

  我们可以考虑转化一下思路,转而求每条边的贡献。我们考虑对于一个点\(x\)满足\(y_x\in[l,r]\),那么\(LCA(u,x)\)一直到根的路径都要被计算一次。那么我们就可以对于每个\(y_x\in[l,r]\),把点\(x\)往上跳,途中经过的边标记加\(1\)。那么最后我们再从\(u\)往上跳,每条边的的标记数就是这条边被计算的次数。那么我们就只需要快速维护一个点到根的路径即可。这个可以树链剖分之后用权值线段树解决。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 150010
#define MAXN 6000010
#define point pair<int,int>
#define sa first
#define sb second using namespace std;
typedef long long llg; point s[maxn];
int n,Q,A,a[maxn],da[maxn],ld,dep[maxn],c1[maxn];//c1[x]表示[1,x]出现的次数和
int head[maxn],next[maxn<<1],to[maxn<<1],c[maxn<<1],tt;//邻接表
int fa[maxn],top[maxn],siz[maxn],son[maxn],tc[maxn],wd[maxn],fd[maxn];//树链剖分
int rt[maxn],addv[MAXN],le[MAXN],ri[MAXN],L,R,CO,_1,_2;//主席树
llg ans,c2[maxn],sumv[MAXN],ji;//c2[x]表示∑dep[u](a[u]∈[1,x]) int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} void link(int x,int y){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
c[tt]=c[tt-1]=getint();
} void dfs(int u){
siz[u]=1; c1[a[u]]++; c2[a[u]]+=dep[u];
for(int i=head[u],v;v=to[i],i;i=next[i])
if(!siz[v]){
dep[v]=dep[u]+c[i];
fa[v]=u; dfs(v); siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
} void dfs(int u,int ot){
top[u]=ot; tc[u]=++tt;
wd[tt]=dep[u]; fd[tt]=dep[fa[u]];
if(son[u]) dfs(son[u],ot);
for(int i=head[u],v;v=to[i],i;i=next[i])
if(!top[v]) dfs(v,v);
} void add(int &u,int l,int r){
tt++; addv[tt]=addv[u];
le[tt]=le[u],ri[tt]=ri[u];
sumv[tt]=sumv[u]; u=tt;
int mid=(l+r)>>1;
if(l>=L && r<=R){
sumv[u]+=wd[r]-fd[l];
addv[u]++; return;
}
if(L<=mid) add(le[u],l,mid);
if(R>mid) add(ri[u],mid+1,r);
sumv[u]=sumv[le[u]]+sumv[ri[u]];
sumv[u]+=(llg)addv[u]*(wd[r]-fd[l]);
} void work(int u,int co){
while(u){
L=tc[top[u]],R=tc[u];
add(rt[co],1,n); u=fa[top[u]];
}
} void query(int u1,int u2,int l,int r){
int mid=(l+r)>>1;
if(l>=L && r<=R){
ji+=sumv[u2]+(llg)_2*(wd[r]-fd[l]);
ji-=sumv[u1]+(llg)_1*(wd[r]-fd[l]);
return;
}
_1+=addv[u1]; _2+=addv[u2];
if(L<=mid) query(le[u1],le[u2],l,mid);
if(R>mid) query(ri[u1],ri[u2],mid+1,r);
_1-=addv[u1]; _2-=addv[u2];
} int up(int x){//二分>=x的第一个
int l=1,r=ld,mid;
while(l!=r){
mid=(l+r)>>1;
if(da[mid]>=x) r=mid;
else l=mid+1;
}
return l;
} int lo(int x){//二分<=x的第一个
int l=1,r=ld,mid;
while(l!=r){
mid=(l+r+1)>>1;
if(da[mid]<=x) l=mid;
else r=mid-1;
}
return l;
} int main(){
File("shop");
n=getint(); Q=getint(); A=getint(); ld=n;
for(int i=1;i<=n;i++) a[i]=da[i]=getint(); da[++ld]=A+1; da[++ld]=0;
sort(da+1,da+ld+1); ld=unique(da+1,da+ld+1)-da-1;
for(int i=1;i<=n;i++) a[i]=up(a[i]),s[i]=make_pair(a[i],i);
for(int i=1;i<n;i++) link(getint(),getint());
tt=0; dfs(1); dfs(1,1); sort(s+1,s+n+1); tt=0;
for(int i=1;i<=ld;i++) c1[i]+=c1[i-1],c2[i]+=c2[i-1];
for(int i=1;i<=n;i++){
if(s[i].sa!=s[i-1].sa) rt[s[i].sa]=rt[s[i-1].sa];
CO=s[i].sa; work(s[i].sb,s[i].sa);
}
rt[ld]=rt[ld-1];
while(Q--){
int u=getint(),aa=getint(),bb=getint(),l,r; ji=0;
(aa+=ans%A)%=A; (bb+=ans%A)%=A;
l=min(aa,bb),r=max(aa,bb); l=up(l); r=lo(r);
if(l>r) ans=ji=0;
else{
ans=c2[r]-c2[l-1]+(llg)(c1[r]-c1[l-1])*dep[u];
while(u){
L=tc[top[u]],R=tc[u];
query(rt[l-1],rt[r],1,n);
u=fa[top[u]];
}
ans-=ji<<1;
}
printf("%lld\n",ans);
}
return 0;
}

BZOJ 4012 【HNOI2015】 开店的更多相关文章

  1. bzoj 4012: [HNOI2015]开店

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

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

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

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

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

  4. BZOJ 4012 [HNOI2015]开店 (树分治+二分)

    题目大意: 给你一棵树,边有边权,点有点权,有很多次询问,求点权$\in[l,r]$的所有节点到某点$x$的距离之和,强制在线 感觉这个题应该放在动态点分之前做= = 套路方法和动态点分是一样的 每次 ...

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

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

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

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

  7. [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MBSubmit: 2168  Solved: 947[Submit][Status] ...

  8. [HNOI2015]开店 树链剖分,主席树

    [HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...

  9. 洛谷 P3241 [HNOI2015]开店 解题报告

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

  10. Luogu 3241 [HNOI2015]开店

    BZOJ 4012权限题 浙科协的网突然炸了,好慌…… 据说正解是动态点分治,然而我并不会,我选择树链剖分 + 主席树维护. 设$dis_i$表示$i$到$root(1)$的值,那么对于一个询问$u$ ...

随机推荐

  1. 【BZOJ2157】旅游 树链剖分+线段树

    [BZOJ2157]旅游 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本 ...

  2. Android 通过Socket 和服务器通讯

    Extends:(http://www.cnblogs.com/likwo/p/3641135.html) Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大 ...

  3. Nexus介绍

    转自:https://www.cnblogs.com/wincai/p/5599282.html 开始在使用Maven时,总是会听到nexus这个词,一会儿maven,一会儿nexus,当时很是困惑, ...

  4. Python - 字符串的方法及注释

    %r非常有用,他的含义是不管是整形还是字符串,都将打印出来

  5. Strongly connected---hdu4635(强联通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 先判断图是否强连通.如果不是强连通的,那么缩点. 我们的目的是加最多的边,那么最后的图中,肯定两 ...

  6. Ubuntu18.04下安装比特币客户端

    一.下载有两种安装方式:安装包和源码 二.安装1.通过安装包安装在https://bitcoin.org/en/download下载Windows,Mac OSX,Linux对应的安装包.安装过程比较 ...

  7. centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课

    centos    LAMP第二部分apache配置  下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转  配置apache的访问日志  配置静态文件缓存  配置防盗链 ...

  8. 002-Spring Framework-Core-01-IoC容器

    一.概述 文章地址:https://docs.spring.io/spring/docs/5.0.6.RELEASE/spring-framework-reference/ 核心主要包括:IoC co ...

  9. 运行HBase应用开发程序产生异常,提示信息包含org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory的解决办法

    Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties Exception in thread ...

  10. PAT 1142 Maximal Clique[难]

    1142 Maximal Clique (25 分) A clique is a subset of vertices of an undirected graph such that every t ...