P3241 [HNOI2015]开店

题目描述

风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学。最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱。

这样的想法当然非常好啦,但是她们也发现她们面临着一个问题,那就是店开在哪里,面向什么样的人群。很神奇的是,幻想乡的地图是一个树形结构,幻想乡一共有 \(n\)个地方,编号为 \(1\) 到 \(n\) 被\(n-1\) 条带权的边连接起来。每个地方都住着一个妖怪,其中第 \(i\) 个地方的妖怪年龄是 \(x_i\) 。

妖怪都是些比较喜欢安静的家伙,所以它们并不希望和很多妖怪相邻。所以这个树所有顶点的度数都小于或等于 \(3\)。妖怪和人一样,兴趣点随着年龄的变化自然就会变化,比如我们的\(18\) 岁少女幽香和八云紫就比较喜欢可爱的东西。幽香通过研究发现,基本上妖怪的兴趣只跟年龄有关,所以幽香打算选择一个地方\(u\) (\(u\) 为编号),然后在\(u\)开一家面向年龄在 \(L\) 到 \(R\) 之间(即年龄大于等于 \(L\) 小于等于 \(R\) )的妖怪的店。

也有可能 \(u\) 这个地方离这些妖怪比较远,于是幽香就想要知道所有年龄在 \(L\) 到 \(R\) 之间的妖怪,到点 \(u\) 的距离的和是多少(妖怪到 \(u\) 的距离是该妖怪所在地方到 \(u\) 的路径上的边的权之和),幽香把这个称为这个开店方案的方便值。

幽香她们还没有决定要把店开在哪里,八云紫倒是准备了很多方案,于是幽香想要知道,对于每个方案,方便值是多少呢。

输入输出格式

输入格式:

第一行三个用空格分开的数 \(n,Q\) 和 \(A\) ,表示树的大小、开店的方案个数和妖怪的年龄上限。

第二行 \(n\) 个用空格分开的数\(x_1,x_2,\ldots,x_n;x_i\) 表示第 \(i\) 个地点妖怪的年龄,满足\(0\le x_i\lt A\) 。(年龄是可以为\(0\)的,例如刚出生的妖怪的年龄为\(0\) 。)

接下来 \(n-1\) 行,每行三个用空格分开的数 \(a\) 、\(b\) 、\(c\) ,表示树上的顶点 \(a\) 和 \(b\) 之间有一条权为\(c(1\le c\le1000)\)的边,\(a\) 和 \(b\) 是顶点编号。

接下来 \(Q\) 行,每行三个用空格分开的数\(u,a,b\) 。

对于这 \(Q\) 行的每一行,用 \(a,b,A\) 计算出 \(L\) 和 \(R\),表示询问在地方 \(u\) 开店,面向妖怪的年龄区间为\([L,R]\) 的方案的方便值是多少“。

对于其中第 \(1\) 行,\(L\) 和 \(R\) 的计算方法为:\(L=\min(a \% A,b \% A),R=\max(a \% A,b \%A)\) 。

对于第 \(2\) 到第 \(Q\) 行,假设前一行得到的方便值为\(ans\) ,那么当前行的 \(L\) 和 \(R\) 计算方法为: \(L=\min((a+ans) \% A,(b+ans) \% A),R=\max((a+ans) \% A, (b+ans)\%A)\)

输出格式:

对于每个方案,输出一行表示方便值。

说明

满足\(n\le1.5\times10^5,Q\le2\times10^5\) 。对于所有数据,满足 \(A\le10^9\)


动态点分=sb码农题+sb卡常题,以上...

要相信同样是两个\(\log\)的算法,有人是\(2s\),有人是\(30s\)

先把点分树弄出来,然后对每个点维护自己在点分树上的子树的每个点到点分树父亲的距离和,最开始我拿的线段树,因为要按年龄划分。

然后预处理是\(O(n\log^2n)\),查询是\(O(\log^2n)\)的

预处理按照点分治那样处理就可以了。

查询暴力向上跳,每次统计一下分治树外的答案+分治树外满足要求的点的个数乘上路径长度。

然后\(ST\)表的一个数组开小了,检查了快\(2h...\),然后卡常也卡不动,本地开\(10s\)才能勉强跑过去。注意这里年龄要先离散化,不然线段树开不下。

考虑没有查询可以直接前缀和,统计的时候拿\(vector\)存一下前缀和然后差分进行询问。询问的时候需要二分一下但是常数就小很多了。

然后咕咕不吸氧还是过不去...


Code:

// luogu-judger-enable-o2
#include <cstdio>
#include <vector>
#include <cctype>
#include <algorithm>
#define ll long long
const int N=150010;
using std::min;
using std::max;
int head[N],to[N<<1],Next[N<<1],edge[N<<1],cnt;
void add(int u,int v,int w)
{
to[++cnt]=v,Next[cnt]=head[u],edge[cnt]=w,head[u]=cnt;
}
char c;int xx;
int read()
{
c=getchar();xx=0;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) {xx=xx*10+c-'0';c=getchar();}
return xx;
}
namespace RMQLCA
{
int dfn[N],st[N<<1][20],dep[N],Log[N<<1],dfs_clock;ll dis[N];
void dfs(int now,int fa)
{
dep[now]=dep[fa]+1;
st[dfn[now]=++dfs_clock][0]=now;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=fa)
dis[v]=dis[now]+edge[i],dfs(v,now),st[++dfs_clock][0]=now;
}
void init()
{
dfs(1,0);
for(int i=2;i<=dfs_clock;i++) Log[i]=Log[i>>1]+1;
for(int j=1;j<=19;j++)
{
for(int x,y,i=1;i<=dfs_clock-(1<<j)+1;i++)
{
x=st[i][j-1],y=st[i+(1<<j-1)][j-1];
st[i][j]=dep[x]<dep[y]?x:y;
}
}
}
ll getdis(int x,int y)
{
ll ret=dis[x]+dis[y];
x=dfn[x],y=dfn[y];
if(x>y) std::swap(x,y);
int d=Log[y+1-x];
x=st[x][d],y=st[y-(1<<d)+1][d];
return ret-(dis[dep[x]<dep[y]?x:y]<<1);
}
}
struct node
{
int age,ct;ll f;
bool friend operator <(node n1,node n2){return n1.age<n2.age;}
};
std::vector <node> sum[N];
std::vector <node>::iterator it;
ll su1=0,su2=0;
void query0(int now,int R)
{
it=std::upper_bound(sum[now].begin(),sum[now].end(),(node){R,0,0});
if(it!=sum[now].begin())
it--,su1=it->f,su2=it->ct;
else
su1=su2=0;
}
int mi,rt,si,siz[N],del[N],par[N];
int n,q,m,poi[N],b[N];ll maxn;
void dfs1(int now,int fa)
{
siz[now]=1;int mx=0;
for(int v,i=head[now];i;i=Next[i])
if(!del[v=to[i]]&&v!=fa)
dfs1(v,now),siz[now]+=siz[v],mx=mx>siz[v]?mx:siz[v];
mx=mx>si-siz[now]?mx:si-siz[now];
if(mi>mx) mi=mx,rt=now;
}
void dfs2(int now,int fa,int w,ll dis)
{
sum[w].push_back((node){poi[now],0,dis});
for(int v,i=head[now];i;i=Next[i])
if(!del[v=to[i]]&&v!=fa)
dfs2(v,now,w,dis+edge[i]);
}
std::vector <int> Edge[N];
void deal(int now)
{
std::sort(sum[now].begin(),sum[now].end());
sum[now][0].ct=1;
for(int i=1;i<sum[now].size();i++)
sum[now][i].f+=sum[now][i-1].f,sum[now][i].ct=i+1;
}
void divide(int now)
{
del[now]=1;
for(int w,v,i=head[now];i;i=Next[i])
{
if(!del[w=to[i]])
{
mi=N,si=siz[w],dfs1(w,0);
dfs2(w,0,v=rt,edge[i]);
deal(v);
par[v]=now,Edge[now].push_back(v);
divide(v);
}
}
}
void getsum(int now,int v,int R,ll &ret1,ll &ret2)
{
ret1=ret2=0;
for(int w,i=0;i<Edge[now].size();i++)
if((w=Edge[now][i])!=v)
su1=su2=0,query0(w,R),ret1+=su1,ret2+=su2;
ret2+=poi[now]<=R;
}
ll query(int now,int R)
{
int las=now;ll ret1,ret2;
getsum(now,0,R,ret1,ret2);
ll ret=ret1;
while(par[now])
{
getsum(par[now],now,R,ret1,ret2);
ret+=ret1;
ret+=ret2*RMQLCA::getdis(las,par[now]);
now=par[now];
}
return ret;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("dew.out","w",stdout);
n=read(),q=read(),maxn=read();
for(int i=1;i<=n;i++) poi[i]=read();
for(int u,v,w,i=1;i<n;i++)
{
u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
RMQLCA::init();
mi=N,si=n;dfs1(1,0),divide(rt);
ll lastans=0;
for(int u,l,r,i=1;i<=q;i++)
{
u=read(),l=read(),r=read();
l=(l+lastans)%maxn,r=(r+lastans)%maxn;
if(l>r) std::swap(l,r);
printf("%lld\n",lastans=(query(u,r)-query(u,l-1)));
}
return 0;
}

2018.12.6

洛谷 P3241 [HNOI2015]开店 解题报告的更多相关文章

  1. 洛谷 P1783 海滩防御 解题报告

    P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...

  2. 洛谷 P4597 序列sequence 解题报告

    P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...

  3. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

  4. 洛谷 P3349 [ZJOI2016]小星星 解题报告

    P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...

  5. 洛谷 P3177 树上染色 解题报告

    P3177 [HAOI2015]树上染色 题目描述 有一棵点数为\(N\)的树,树边有边权.给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色, ...

  6. 洛谷 P4705 玩游戏 解题报告

    P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...

  7. 洛谷 P1272 重建道路 解题报告

    P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...

  8. 洛谷 [HNOI2014]道路堵塞 解题报告

    [HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...

  9. 洛谷 P1452 Beauty Contest 解题报告

    P1452 Beauty Contest 题意 求平面\(n(\le 50000)\)个点的最远点对 收获了一堆计算几何的卡点.. 凸包如果不保留共线的点,在加入上凸壳时搞一个相对栈顶,以免把\(n\ ...

随机推荐

  1. unity游戏在ios11上不显示泰语解决办法

    最近在开发中遇到unity游戏在ios11上不显示泰语的问题,全部显示为方框内一个问号. 通过搜索发现这是Unity的一个bug,在2017.3中修复了 但升级unity风险很大,所以我采用了该文中提 ...

  2. 【SpringCloud】第十一篇: 断路器监控(Hystrix Dashboard)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  3. dubbo 微服务框架

    dubbo 注解配置: @Service //Service注解暴露服务 @Configuration // javaconfig形式配置公共模块 @DubboComponentScan // 指定d ...

  4. 用Python实现多站点运维监控

    在小型公司里如果产品线单一的话,比如就一个app, 一般1~2个运维就够用了.如果产品过于庞大,就需要多个运维人员. 但对于多产品线的公司来说,运维人员就要必须分多个人负责,因为超过200个站点让1个 ...

  5. Paper Reading - Long-term Recurrent Convolutional Networks for Visual Recognition and Description ( CVPR 2015 )

    Link of the Paper: https://arxiv.org/abs/1411.4389 Main Points: A novel Recurrent Convolutional Arch ...

  6. 亚马逊拟斥资15亿美元建航空货运中心 - Amazon to spend $1.49 bln on air cargo hub, fans talk of bigger ambitions - ReutersFebruary 1, 2017

    2月1日消息,亚马逊本周二宣布将在肯塔基州开建其第一个航空货运中心,以应对高速增长的航空货运需求.亚马逊预计,该项目将带来2000个工作岗位. 据悉,该项计划总投入约为15亿美元,亚马逊或可从当地政府 ...

  7. Fluent Python: memoryview

    关于Python的memoryview内置类,搜索国内网站相关博客后发现对其解释都很简单, 我觉得学习一个新的知识点一般都要弄清楚两点: 1, 什么时候使用?(也就是能解决什么问题) 2,如何使用? ...

  8. 谈谈javascript中的变量提升还有函数提升

    在很多面试题中,经常会看到关于变量提升,还有函数提升的题目,所以我就写一篇自己理解之后的随笔,方便之后的查阅和复习. 首先举个例子 foo();//undefined function foo(){ ...

  9. qq浏览器的用户体验

    用户界面: qq浏览器的用户界面简介,把一些不必要的东西去点,可以很容易让用户找到自己想看的网页,很方便. 记住用户的选择: qq浏览器和QQ相连,可是用QQ账户登录,并且会记住自己访问的高频网页,以 ...

  10. 对石家庄铁道大学网站UI的分析

         作为我们团队的PM,老师对我们提出了一些额外的要求,所以我发表这篇博客来谈一下对石家庄铁道大学网站UI的分析.      首先,PM 对项目所有功能的把握, 特别是UI.最差的UI, 体现了 ...