好久没写数据结构了

来补一发

果然写的时候思路极其混乱....

LOJ #2116 Luogu P3241


题意

$ Q$次询问,求树上点的颜色在$ [L,R]$中的所有点到询问点的距离 强制在线

询问次数,树上点数约$ 2·10^5$


$ Solution$

首先有

$ dist(x,y)=deep(x)+deep(y)-2·deep(lca(x,y))$

显然这个等式的前两项很容易用前缀和什么的维护

只考虑第三项的话相当于是有边权并且强制在线的「LNOI2014」LCA

用同样的套路将$ deep(lca(x,y))$转化成对于所有在区间中的点,将其到根的路径区间加

然后查询询问点到根的距离

将所有点按颜色排序 树剖+主席树维护

每次将当前颜色最小的点插入主席树 最多影响$ log^2$个线段

注意需要标记永久化

写的时候思路很不清楚感觉写了假的主席树


$my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define M 150010
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans;
int dfn[M],top[M],size[M],fa[M],to[M];ll deep[M];
vector<pair<int,int>>e[];
void dfs(int x,int pre){
size[x]=;fa[x]=pre;
for(auto i:e[x])if(i.first!=pre){
deep[i.first]=deep[x]+i.second;
dfs(i.first,x);size[x]+=size[i.first];
}
}
void dfs2(int x,int chain){
int heavy=;dfn[x]=++cnt;top[x]=chain;to[cnt]=x;
for(auto i:e[x])if(size[i.first]>size[heavy]&&i.first!=fa[x])heavy=i.first;
if(!heavy)return;
dfs2(heavy,chain);
for(auto i:e[x])if(i.first!=heavy&&i.first!=fa[x])dfs2(i.first,i.first);
}
struct segment{
int ls,rs,tag;ll sum;
}a[];
int Root[];
#define up a[x].sum=(ll)a[a[x].ls].sum+a[a[x].rs].sum+(ll)a[x].tag*(deep[to[R]]-deep[fa[to[L]]])
void change(int x,int L,int R,int LL,int RR){
const int mid=L+R>>;
if(L>=LL&&R<=RR){
a[x].tag++;
up;return;
}
if(mid>=LL){
if(a[x].ls)a[cnt+]=a[a[x].ls];
change(a[x].ls=++cnt,L,mid,LL,RR);
}
if(mid+<=RR){
if(a[x].rs)a[cnt+]=a[a[x].rs];
change(a[x].rs=++cnt,mid+,R,LL,RR);
}
up;
}
ll query(int x,int LL,int RR,int L,int R,int cs){
if(!x)x=++cnt;if(LL>R||RR<L)return ;
if(LL>=L&&RR<=R)return a[x].sum+(ll)cs*(deep[to[RR]]-deep[fa[to[LL]]]);
const int mid=LL+RR>>;
return query(a[x].ls,LL,mid,L,R,cs+a[x].tag)+query(a[x].rs,mid+,RR,L,R,cs+a[x].tag);
}
void upd(int id,int x){
while(x){
change(Root[id],,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
}
ll query(int id,int x){
if(!id)return ;
ll ans=;
while(x){
ans+=query(Root[id],,n,dfn[top[x]],dfn[x],);
x=fa[top[x]];
}
return ans;
}
struct peri{
int x,id;
bool operator <(const peri s){
return x<s.x;
}
}q[];
ll s[];
int main(){
n=read();m=read();int A=read();
for(rt i=;i<=n;i++)q[i].x=read(),q[i].id=i;
sort(q+,q+n+);fa[]=;
for(rt i=;i<=n;i++){
x=read();y=read();z=read();
e[x].push_back({y,z});e[y].push_back({x,z});
}
dfs(,);dfs2(,);cnt=;
for(rt i=;i<=n;i++)s[i]=s[i-]+deep[q[i].id];//前i小的deep和
for(rt i=;i<=n;i++){
Root[i]=++cnt;
a[Root[i]]=a[Root[i-]];
upd(i,q[i].id);
}
ll las=;
while(m--){
z=read();int aa=read(),bb=read();
int L=min((aa+las)%A,(bb+las)%A);
int R=max((aa+las)%A,(bb+las)%A);
L=lower_bound(q+,q+n+,(peri){L,})-q;
R=lower_bound(q+,q+n+,(peri){R+,})-q-;
las=(ll)(R-L+)*deep[z]+s[R]-s[L-]-(query(R,z)-query(L-,z))*;
writeln(las);
}
return ;
}

LOJ #2116 Luogu P3241「HNOI2015」开店的更多相关文章

  1. loj #2116. 「HNOI2015」开店

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

  2. LOJ #2547 Luogu P4517「JSOI2018」防御网络

    好像也没那么难写 LOJ #2547 Luogu P4517 题意 在一棵点仙人掌中等概率选择一个点集 求选出点集的斯坦纳树大小的期望 定义点仙人掌为不存在一个点在多个简单环中的连通图 斯坦纳树为在原 ...

  3. LOJ#2249 Luogu P2305「NOI2014」购票

    几乎肝了半个下午和整个晚上 斜率优化的模型好多啊... LOJ #2249 Luogu P2305 题意 给定一棵树,第$ i$个点如果离某个祖先$ x$的距离不超过$ L_i$,可以花费$ P_i· ...

  4. LOJ #2527 Luogu P4491「HAOI2018」染色

    好像网上没人....和我推出....同一个式子啊..... LOJ #2527 Luogu P4491 题意 $ n$个格子中每个格子可以涂$ m$种颜色中的一种 若有$ k$种颜色恰好涂了$ s$格 ...

  5. 【LOJ】#2116. 「HNOI2015」开店

    题解 一道我觉得和二叉树没有关系的题-- 因为直接上点分就过了,虽然很慢,而且代码很长 你需要记录一个点分树,对于每个点分树的重心,记录一下上一次进行分割时树的重心以及这个重心和上一次重心所连接的点以 ...

  6. [loj2116]「HNOI2015」开店 动态点分治

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

  7. 「HNOI2015」开店(树链剖分, 主席树)

    /* 考虑将所求的值拆分 记每个点到根的路径长度为dis_i, 那么我们要求的就是\sum_{i = l} ^ r dis_i + dis[u] * (r - l + 1) - 2\sum_{i = ...

  8. 「HNOI2015」菜肴制作

    「HNOI2015」菜肴制作 这道题想到了其实还挺水的,一开始我直接用小根堆拓扑然后就爆0了,然后我又用十万个堆搜索,T30,还是xkl告诉我要倒着拓扑. 首先要建反图,对于入度为0的点,较小的点先输 ...

  9. 【LOJ】#2117. 「HNOI2015」实验比较

    题解 把所有=的点连起来,一个图合法肯定它是一个有向树森林 我们新建一个点,把这个点和其他所有树的树根连起来 定义\(dp[u][j]\)表示第u个点长度为j的序列的方案数 转移方法是 \(dp[u] ...

随机推荐

  1. spring boot 2.0 WebMvcConfigurerAdapter过时解决方法

    第一种: @Configuration public class WebAppConfig implements WebMvcConfigurer{ @Bean public HandlerInter ...

  2. 基于SpringMVC拦截器和注解实现controller中访问权限控制

    SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法. preHandle在业务处理器 ...

  3. Docker启动Get Permission Denied

    https://www.cnblogs.com/informatics/p/8276172.html 以下问题及解决方法都在Ubuntu16.04下,其他环境类似 问题描述 安装完docker后,执行 ...

  4. 【原创】IDEA一定要改的八条配置

    引言 坦白说,我很少写这种操作类型的文章.因为这种文章没啥新意,大家操作步骤肯定是一样的.然而,我答应了我的同事小阳,给她出一篇!毕竟人家打算从Eclipse转IDEA了,于是以示鼓励,写一篇给她! ...

  5. 《React Native 精解与实战》书籍连载「React Native 源码学习方法及其他资源」

    此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React Native 源码学习方法及其他资源. 最后的章节给大家介绍 React Native ...

  6. 关于toncat的Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986

    首先这个错误通常的产生原因, 是tomcat的确收到了格式不正确的请求参数,根据tomcat的版本支持的解析,tomcat抛出这个错误. 但是还有一种就是前台发送的请求方式由 get发送导致本应pos ...

  7. ASP.NET下MVC设计模式的实现

    [转载]MVC架构在Asp.net中的应用和实现 转载自:http://www.cnblogs.com/baiye7223725/archive/2007/06/07/775390.aspx 摘要:本 ...

  8. vue脚手架搭建移动端项目--flexible.js

    通过命令行 node -v 查看是否安装node环境 在 nodejs 和 webpack已安装的前提下,随便一个文件夹下,输入命令行 npm install vue-cli -g 安装完成后,通过 ...

  9. dubbo在idea下的使用创建 服务者,消费者 注册中心

    1.基于windows 下  spring 下的dubbo  需要书写配置文件 (1).创建带有web工程的项目 创建一个服务者 package cn.edu.aynu.bean; import lo ...

  10. java学习之—实现一个简单的ArrayList

    package thread1; /** * 实现一个简单的ArrayList * * @Title: uminton */ public class SimpleArrayList<T> ...