BZOJ4012 [HNOI2015]开店

BZOJ4012 [HNOI2015]开店

这道题因为太多人拿这个题卡$BZOJ$,于是成了权限题。。。

本蒟蒻表示没钱氪金。。。

无奈,拿出了洛谷:P3241 [HNOI2015]开店

还有$LOJ$:#2116. 「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$ ,表示树的大小、开店的方案个数和妖怪的年龄上限。

第二行nn 个用空格分开的数$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)$ 。

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 复制
10 10 10
0 0 7 2 1 4 7 7 7 9
1 2 270
2 3 217
1 4 326
2 5 361
4 6 116
3 7 38
1 8 800
6 9 210
7 10 278
8 9 8
2 8 0
9 3 1
8 0 8
4 2 7
9 7 3
4 7 0
2 2 7
3 2 1
2 3 4
输出样例#1: 复制
1603 
957 
7161 
9466 
3232 
5223 
1879 
1669 
1282 
0

说明

满足$n\le1.5\times 10^5,Q\le2\times 10^5$ 。对于所有数据,满足$A<=10^9$


 

题解Here!

感觉做完这题之后,自己的码力和几个月前不一样了。。。

据说这题是动态淀粉质点分治?然而本蒟蒻并不会。。。

有时间再填坑吧感觉这辈子是不可能填坑的。。。

于是拿出了树链剖分+主席树。

每次询问点权在$[L,R]$之间的所有点到某个点的距离之和,并且强制在线。

首先考虑一个简化的版本:

询问所有点到点$u$的距离和。

然后开始漫长地推式子。。。

当然,可以跳过漫长的过程直接看结论。。。

设$deep[i],size[i]$分别表示以$1$为根时第$i$个点的带权深度和子树大小。

在我的代码中为了避免变量名冲突,就用$dis[i]$代替了这里的$deep[i]$,这点要注意一下。

观察$1$为根和$u$为根会发生哪些变化。

$u$的子树中某节点$v$的深度会从$deep[v]$变成$deep[v]-deep[u]$,相当于都减少了$deep[u]$,且有$size[u]$个点发生了此变化。

$fa[u]$的子树,且不是$u$的子树中的某节点$v$,深度会从$deep[v]$变成$deep[v]-deep[fa[u]]+deep[u]-deep[fa[u]]$,相当于减少了$2\times deep[fa[u]]-deep[u]$,且有$size[fa[u]]-size[u]$个点发生了此变化。

之后以此类推。

更具体的描述,定义$a_i$为$1$至$u$的链上的第$i$个点,$1$至$u$的链上共有$k$个点,那么所有点到$u$的距离之和可以用如下式子表示:

$$\sum_{i=1}^ndeep[i]-\sum_{i=1}^{k-1}(size[a_i]-size[a_i+1])\times (2\times deep[a_i]-deep[u])-size[u]\times deep[u]$$

展开:

$$\sum_{i=1}^ndeep[i]-size[u]\times deep[u]-(2\times \sum_{i=1}^{k-1}size[a_i]\times deep[a_i]-2\times\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[a_i]-\sum_{i=1}^{k-1}size[a_i]\times deep[u]+\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[u])$$

$$=\sum_{i=1}^ndeep[i]-size[u]\times deep[u]-2\times\sum_{i=1}^{k-1}size[a_i]\times deep[a_i]+2\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[a_i]+\sum_{i=1}^{k-1}size[a_i]\times deep[u]-\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[u]$$

把其中的某个式子提出来,化简:

$$\sum_{i=1}^{k-1}size[a_i]\times deep[u]-\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[u]$$

$$=\sum_{i=1}^{k-1}size[a_i]\times deep[u]-\sum_{i=2}^ksize[a_i]\times deep[u]$$

$$=size[a_1]\times deep[u]-size[a_k]\times deep[u]$$

$$=n\times deep[u]-size[u]\times deep[u]$$

于是原式变为:

$$\sum_{i=1}^ndeep[i]+n\times deep[u]-2\times size[u]\times deep[u]-2\times \sum_{i=1}^{k-1}size[a_i]\times deep[a_i]+2\times \sum_{i=1}^{k-1}size[a_{i+1}]\times deep[a_i]$$

现在观察:

$$-2\sum_{i=1}^{k-1}size[a_i]\times deep[a_i]+2\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[a_i]$$

即:

$$2\sum_{i=1}^{k-1}size[a_{i+1}]\times deep[a_i]-2\sum_{i=1}^{k-1}size[a_i]\times deep[a_i]$$

这里直接相减出现的$size[a_i]-size[a_{i+1}]$难以处理,我们考虑进行错位相减。

$$\text{原式}=2\sum_{i=2}^ksize[a_i]\times deep[a_{i-1}]-2\sum_{i=1}^{k-1}size[a_i]\times deep[a_i]$$

$$=2\sum_{i=2}^ksize[a_i]\times deep[a_{i-1}]-2\sum_{i=2}^{k-1}size[a_i]\times deep[a_i](deep[a_1]=deep[1]=0)$$

$$=2\times size[a_k]\times deep[a_{k-1}]+2\sum_{i=2}^{k-1}size[a_i]\times (deep[a_{i-1}]-deep[a_i])$$

将原式中的$-2\times size[u]\times deep[u]$并入上式中,得到:

$$2\times size[a_k]\times deep[a_{k-1}]-2\times size[a_k]\times deep[a_k]+2\sum_{i=2}^{k-1}size[a_i]\times (deep[a_{i-1}]-deep[a_i])$$

$$=2\sum_{i=2}^ksize[a_i](deep[a_{i-1}]-deep[a_i])$$

注意到$deep[a_i]-deep[a_{i-1}]$是点$i$到其父节点的边权,设为$fv[i]$。

故原式等于:

$$\sum_{i=1}^ndeep[i]+n\times deep[u]-2\sum_{i=2}^ksize[a_i]\times fv[a_i]$$

到此,我们的推式子结束了。

并且这玩意可以进行维护了。

现在考虑如何加入$[L,R]$的限制。

直接通过子树查询的方式进行,单次复杂度与树高约为线性关系,显然是铁定$TLE$的。

怎么办?

这时便要体会主席树的版本作用。

将点按照点权排序,一个一个加入,最终答案便是$R$对应版本的主席树的答案减去$L-1$对应版本的主席树的答案。

也就是做一个差分:$Ans(L,R)=Ans(1,R)-Ans(1,L-1)$

而且,每次加入一个点的时候,树的形态不发生变化,$fv[i]$不发生变化,只有$size[i]$发生变化。

所以只需把加入的这个点到根的路径上的所有点的$size$进行$+1$即可。

查询时从当前指定的点出发,向上统计$\sum size[i]\times fv[i]$。

这是可以通过树链剖分维护的。

由于空间限制,需要使用标记永久化。

这题目就做完了。

好长。。。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 200010
using namespace std;
int n,m,age,c=1,d=1;
int root[MAXN];
int head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],pos[MAXN],top[MAXN];
long long dis[MAXN],sum[MAXN];
struct Tree{int next,to,w;
}a[MAXN<<1];
struct Point{int val,id;friend bool operator <(const Point &p,const Point &q){if(p.val==q.val)return p.id<q.id;return p.val<q.val;}
}point[MAXN];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
namespace CT{#define LSON(x) a[x].l#define RSON(x) a[x].r#define DATA(x) a[x].data#define SUM(x) a[x].sum#define SIGN(x) a[x].cint size=0;struct Chairman_Tree{long long data,sum;int l,r,c;}a[MAXN<<7];inline void pushup(int rt){DATA(rt)=DATA(LSON(rt))+DATA(RSON(rt));SUM(rt)=SUM(LSON(rt))+SUM(RSON(rt))+DATA(rt)*SIGN(rt);}inline void buildtree(int l,int r,int &rt){a[++size]=a[rt];rt=size;SIGN(rt)=LSON(rt)=RSON(rt)=SUM(rt)=DATA(rt)=0;if(l==r){DATA(rt)=dis[pos[l]]-dis[fa[pos[l]]];return;}int mid=l+r>>1;buildtree(l,mid,LSON(rt));buildtree(mid+1,r,RSON(rt));pushup(rt);}void update(int l,int r,int lside,int rside,int &rt){a[++size]=a[rt];rt=size;if(l<=lside&&rside<=r){SIGN(rt)++;SUM(rt)+=DATA(rt);return;}int mid=lside+rside>>1;if(l<=mid)update(l,r,lside,mid,LSON(rt));if(mid<r)update(l,r,mid+1,rside,RSON(rt));pushup(rt);}long long query(int l,int r,int c,int lside,int rside,int rt){long long ans=0;if(l<=lside&&rside<=r)return (SUM(rt)+DATA(rt)*c);c+=SIGN(rt);int mid=lside+rside>>1;if(l<=mid)ans+=query(l,r,c,lside,mid,LSON(rt));if(mid<r)ans+=query(l,r,c,mid+1,rside,RSON(rt));return ans;}
}
inline void add(int u,int v,int w){a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;a[c].to=u;a[c].w=w;a[c].next=head[v];head[v]=c++;
}
void dfs1(int rt){son[rt]=0;size[rt]=1;for(int i=head[rt];i;i=a[i].next){int will=a[i].to;if(!deep[will]){deep[will]=deep[rt]+1;dis[will]=dis[rt]+a[i].w;fa[will]=rt;dfs1(will);size[rt]+=size[will];if(size[son[rt]]<size[will])son[rt]=will;}}
}
void dfs2(int rt,int f){id[rt]=d++;pos[id[rt]]=rt;top[rt]=f;if(son[rt])dfs2(son[rt],f);for(int i=head[rt];i;i=a[i].next){int will=a[i].to;if(will!=fa[rt]&&will!=son[rt])dfs2(will,will);}
}
void update_path(int x,int y,int u){while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]])swap(x,y);CT::update(id[top[x]],id[x],1,n,root[u]);x=fa[top[x]];}if(deep[x]>deep[y])swap(x,y);CT::update(id[x],id[y],1,n,root[u]);
}
long long query_path(int x,int y,int u){long long s=0;while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]])swap(x,y);s+=CT::query(id[top[x]],id[x],0,1,n,root[u]);x=fa[top[x]];}if(deep[x]>deep[y])swap(x,y);s+=CT::query(id[x],id[y],0,1,n,root[u]);return s;
}
long long solve(int x,int u){return (sum[u]+dis[x]*u-2LL*query_path(1,x,u));
}
void work(){int l,r,u;long long last=0;while(m--){u=read();l=read();r=read();l=(l+last)%age;r=(r+last)%age;if(l>r)swap(l,r);l=lower_bound(point+1,point+n+1,(Point){l,0})-point;r=upper_bound(point+1,point+n+1,(Point){r,MAXN})-point-1;last=solve(u,r)-solve(u,l-1);printf("%lld\n",last);}
}
void init(){int u,v,w;n=read();m=read();age=read();for(int i=1;i<=n;i++){point[i].val=read();point[i].id=i;}for(int i=1;i<n;i++){u=read();v=read();w=read();add(u,v,w);}deep[1]=1;dfs1(1);dfs2(1,1);sort(point+1,point+n+1);CT::buildtree(1,n,root[0]);for(int i=1;i<=n;i++){sum[i]=sum[i-1]+dis[point[i].id];root[i]=root[i-1];update_path(1,point[i].id,i);}
}
int main(){init();work();return 0;
}

 

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9601611.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch实战-入门

1.概述 今天接着《ElasticSearch实战&#xff0d;日志监控平台》一文来给大家分享后续的学习&#xff0c;在《ElasticSearch实战&#xff0d;日志监控平台》中给大家介绍一个日志监控平台的架构方案&#xff0c;接下来给大家分享如何去搭建部署这样一个平台&#xff0c;给大家做…

macos 版本_如何检查您使用的macOS版本

macos 版本Apple releases new versions of the macOS operating system about once per year. Here’s how to check which release of the macOS operating system is installed on your MacBook, iMac, Mac Mini, or Mac Pro. 苹果大约每年发布一次新版本的macOS操作系统。 …

第十四周作业

2019春第二次课程设计实验报告 一.实验项目 贪吃蛇游戏 二.实验功能描述&#xff1a; 存储数据&#xff0c;实现wasd控制蛇方向&#xff0c;吃到食物就增加长度&#xff0c;最后按长度算分数&#xff0c;撞到障碍物则死亡&#xff0c;计算积分 三.项目模板结构介绍&#xff1a;…

java语言不用担心内存吗_不用担心智能手机的电池,只需使用它

java语言不用担心内存吗When you’re trying to get the most life out of your device, it’s easy to overthink batteries. Don’t. Plug in your devices when possible, carry a battery pack with you, and get on with your life. 当您试图充分利用设备的使用寿命时&…

asp.net core结合NLog搭建ELK实时日志分析平台

0、整体架构 整体架构目录&#xff1a;ASP.NET Core分布式项目实战-目录 一、介绍ELK 1、说明&#xff08;此篇ELK采用rpm的方式安装在服务器上&#xff09;-牛刀小试 承接上一篇文章的内容准备部署ELK来展示asp.net core 的数据。目前此篇文章只用到单台服务器&#xff0c;等下…

Rhel7 设置目录权限,acl权限

Rhel7 设置目录权限&#xff0c;acl权限 改变用户和组的所属 Getfacl 取得 Setfacl设置 [rootdesktop0 tmp]# setfacl -m u:natasha:rw fstab [rootdesktop0 tmp]# setfacl -m u:harry:- fstab [rootdesktop0 tmp]# setfacl -m o::r fstab [rootdesktop0 tmp]# getfacl fstab #…

IT兄弟连 JavaWeb教程 AJAX定义以及解决的问题

2019独角兽企业重金招聘Python工程师标准>>> Ajax是"Asynchronous JavaScript And XML"的缩写(即&#xff1a;异步的JavaScript和XML)&#xff0c;是一种实现无页面刷新获取服务器数据的混合技术,Ajax这个概念的最早提出者是Jesse James Garrett。我们知道…

echo和@echo_如何在Echo Show和Echo Spot上切换到24小时时钟

echo和echoIf you prefer the 24-hour clock format instead of the usual 12-hour format, Amazon recently (and quietly) added the ability to switch between the two on the Echo Show and Echo Spot. 如果您希望使用24小时制而不是通常的12小时制&#xff0c;那么Amazon…

生信入门-爱课程上的华中农业大学

1.生物大分子序列分析 2.主要技术 3.生物信息学的应用 4.应用2 转载于:https://www.cnblogs.com/BlueBlueSea/p/9610313.html

pc端文本_使用即将推出的Windows功能从PC发送文本

pc端文本Windows/Android/iPhone: Send and receive SMS messages on your PC, and access all the files on your phone without taking it out of your pocket. Windows / Android / iPhone&#xff1a;在PC上发送和接收SMS消息&#xff0c;并访问手机上的所有文件&#xff0…

非常详细的Exchange 功能路线图

非常详细的Exchange 功能路线图 此路线图可帮助您熟悉 Microsoft Exchange Server 2010 中的所有功能。第一部分列出了可通过 Exchange 管理控制台 (EMC) 或 Exchange 命令行管理程序管理的所有功能。该部分还说明如何在 EMC 中导航至功能&#xff0c;并提供指向相应管理主题的…

String类常用方法

定义方法类型描述public String(char[] value)构造直接将一个字符数组变为一个字符串public String(char[] value,int offset,int count)构造将一个指定范围的字符数组变为字符串public String(byte[] bytes)构造将一个byte数组全部变为字符串public String(byte[],bytes,int o…

python基础一 day6 文件操作

读写只会进行两步&#xff0c; r模式下写读 seek是按字节去找的 for line in f: for循环是一行一行的读取出来 strip默认去空格和换行符 空格、制表符、换行符、回车、换页垂直制表符和换行符称为 “空白字符” for in 一个不可变数据类型&#xff0c;比如字符串&#xff0c;先…

静态路由默认路由的配置

静态路由实验 负载均衡的一点是个人理解&#xff0c;有不正确之处欢迎批评指正。 R1配置: s0/0/0口&#xff1a;193.1.1.9/30(本地) next-hop 193.1.1.10/30 point-to-point link F0/0设置子接口&#xff1a;F0/0.1 172.17.115.1/24 VLAN1 F0/0.5 172.17.110…

r中汇率市场_如何在Word 2013表中汇总行和列

r中汇率市场If you’re working in Word and you need to total values in a table, you can do so without having to enter the data into Excel and then copy and paste it into Word. Word can do simple calculations such as summing, multiplying, and averaging. 如果…

敏捷开发

敏捷开发是1990年逐渐引起人们广泛关注的新型软件开发方式,它是具有应对快速变化需求的软件开发能力。相对于非敏捷开发&#xff0c;它是一种以客户需求为核心&#xff0c;持续迭代&#xff0c;循序渐进的开发方式&#xff0c;敏捷绝非是一种特定的开发方式&#xff0c;而是一种…

数据同步云端本地_如何从云端删除Windows 8的同步数据

数据同步云端本地The ability to sync data and settings between computers running Windows 8 is great, but it does mean that your information – possibly personal – is stored in the cloud. If you have changed your mind about syncing and want to remove your d…

前端roadmap

转载于:https://www.cnblogs.com/cleverle/p/9615061.html

国内是否可以安装alexa_Alexa可以听到您无法听到的命令,哪些黑客可以利用

国内是否可以安装alexaYour smart speaker can hear sounds that humans can’t, meaning attackers could hypothetically trigger a command without you noticing. It’s happening in labs right now. 您的智能扬声器可以听到人类听不到的声音&#xff0c;这意味着攻击者可…

ActiveMQ在windows下启动失败解决方案

activemq.xml文件中的<transportConnectors><!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --><transportConnector name"openwire" uri"tcp://0.0.0.0:61616?maximumConnections1000&amp;wireForma…