题目链接:开店

  这道题显然一眼树分治,维护点分的结构,在每个点上,对每种年龄到这个点\(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. Mysql group_concat函数列转行,与行转列

    例一: SELECT num from user 1.使用group_concat函数得到列转行 select group_concat(num) from user 2.使用SUBSTRING_IN ...

  2. AngularJS』一点小小的理解

    『AngularJS』一点小小的理解   AngularJS 是一个前端的以Javascript为主的MVC框架.与AngularJS相类似的还有EmberJS. 随着时代在进步,各种各样的开发理念与 ...

  3. 几行小代码,将Testlink的xml用例导入至excel

    最近在使用Testlink时,发现导入的用例是xml格式,且没有合适的工具转成excel格式,xml使用excel打开显示的东西也太多,网上也有相关工具转成csv格式的,结果也不合人意. 那求人不如尔 ...

  4. jquery实现ajax跨域请求!亲测有效

    在解决跨域的时候,我通常会用豆瓣api作为尝试. 下面是本地跨域请求豆瓣API:亲测有效: <script type="text/javascript"> var ur ...

  5. Apache配置虚拟主机httpd-vhosts.conf

    一.配置虚拟主机需要3个文件  1.Apache/conf/httpd.conf 2.Apache/conf/extra/httpd-vhosts.conf (这个地版本的apache可能没有,可自己 ...

  6. 编译安装基于nginx与lua的高性能web平台-openresty

    1.首先编译安装nginx(不多说) 2.开始安装openresty cd /usr/local/src wget https://openresty.org/download/openresty-1 ...

  7. 徐州网络赛A-Hard To Prepare【dp】【位运算】【快速幂】

    After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a ...

  8. CF593C Beautiful Function 构造

    正解:构造 解题报告: 传送门! 我知道我咕了好几篇博客似乎,,,但我不听!我就是要发新博客QAQ!(理不直气也壮 这题,想明白了还是比较简单的QwQ实现起来似乎也没有很复杂QAQ 首先思考一下,显然 ...

  9. 【Loadrunner】性能测试报告实战

    一.一份好的性能测试报告需要遵循什么规则? 好的报告只需要遵循3点即可:清晰的结构.简要的语言以及数据的对比. 二.如何用Loadrunner自动到处HTML以及word版的报告? 1.导出html格 ...

  10. 如何确定Hadoop中map和reduce的个数--map和reduce数量之间的关系是什么?

    一般情况下,在输入源是文件的时候,一个task的map数量由splitSize来决定的,那么splitSize是由以下几个来决定的 goalSize = totalSize / mapred.map. ...