【LOJ#6073】距离(主席树)

题面

LOJ

题解

两点间的距离是\(dep[x]+dep[y]-2dep[LCA]\)。

那么题目要求的东西拆开维护,唯一不好做的就是\(2dep[LCA]\)。

而现在要求的是某个单点与一个点集的所有\(LCA\)的深度和。

那么把点集中每一个点到根的路径全部标记一次路径长度,那么只需要求单点到根的权值和就好了。

回到当前题目,既然要求的是一条路径上的东西,那么用主席树维护其到根的点集所影响的权值,最后减一减就好了。

(是不是说得太简单了。。。。)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 200200
inline ll read()
{
ll x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int type,n,Q,p[MAX];
struct Line{int v,next,w;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int dfn[MAX],low[MAX],tim,top[MAX],size[MAX],hson[MAX],dep[MAX],fa[MAX],V[MAX];
ll sum[MAX],ans,dis[MAX],sdis[MAX];
void dfs1(int u,int ff)
{
size[u]=1;fa[u]=ff;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
dis[v]=dis[u]+e[i].w;V[v]=e[i].w;
dfs1(v,u);size[u]+=size[v];
if(size[v]>size[hson[u]])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=fa[u]&&e[i].v!=hson[u])
dfs2(e[i].v,e[i].v);
}
int LCA(int u,int v)
{
while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
return dep[u]<dep[v]?u:v;
}
struct Node{int ls,rs,s;ll v;}t[MAX<<6];
int tot,rt[MAX];
void Modify(int &x,int l,int r,int L,int R)
{
t[++tot]=t[x];x=tot;
if(l==L&&r==R){++t[x].s;return;}
t[x].v+=sum[R]-sum[L-1];int mid=(l+r)>>1;
if(R<=mid)Modify(t[x].ls,l,mid,L,R);
else if(L>mid)Modify(t[x].rs,mid+1,r,L,R);
else Modify(t[x].ls,l,mid,L,mid),Modify(t[x].rs,mid+1,r,mid+1,R);
}
ll Query(int x,int l,int r,int L,int R)
{
ll ret=(sum[R]-sum[L-1])*t[x].s;
if(L==l&&R==r)return ret+t[x].v;
int mid=(l+r)>>1;
if(R<=mid)return ret+Query(t[x].ls,l,mid,L,R);
if(L>mid)return ret+Query(t[x].rs,mid+1,r,L,R);
return ret+Query(t[x].ls,l,mid,L,mid)+Query(t[x].rs,mid+1,r,mid+1,R);
}
void dfs(int u,int ff)
{
rt[u]=rt[ff];int x=p[u];sdis[u]=sdis[ff]+dis[x];
while(top[x])Modify(rt[u],1,n,dfn[top[x]],dfn[x]),x=fa[top[x]];
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=ff)dfs(e[i].v,u);
}
ll Query(int u,int k)
{
ll ret=dis[k]*dep[u]+sdis[u];
while(top[k])ret-=Query(rt[u],1,n,dfn[top[k]],dfn[k])*2,k=fa[top[k]];
return ret;
}
int main()
{
type=read();n=read();Q=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read(),w=read();
Add(u,v,w);Add(v,u,w);
}
dfs1(1,0);dfs2(1,1);
for(int i=1;i<=n;++i)p[i]=read();
for(int i=1;i<=n;++i)sum[dfn[i]]=V[i];
for(int i=1;i<=n;++i)sum[i]+=sum[i-1];
dfs(1,0);
while(Q--)
{
int u=read()^(type*ans),v=read()^(type*ans);
int lca=LCA(u,v),k=read()^(type*ans);
printf("%lld\n",ans=Query(u,k)+Query(v,k)-Query(lca,k)-Query(fa[lca],k));
} }

【LOJ#6073】距离(主席树)的更多相关文章

  1. loj#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 主席树)

    题意 题目链接 Sol 首先对询问差分一下,我们就只需要统计\(u, v, lca(u, v), fa[lca(u, v)]\)到根的路径的贡献. 再把每个点与\(k\)的lca的距离差分一下,则只需 ...

  2. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  3. LOJ 6435 「PKUSC2018」星际穿越——DP+倍增 / 思路+主席树

    题目:https://loj.ac/problem/6435 题解:https://www.cnblogs.com/HocRiser/p/9166459.html 自己要怎样才能想到怎么做呢…… dp ...

  4. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

  5. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  6. LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树

    题目:https://loj.ac/problem/3055 先写了暴力.本来想的是 n<=300 的那个在树上暴力维护好整个字符串, x=1 的那个用主席树维护好字符串和 nxt 数组.但 x ...

  7. BZOJ 2735: 世博会 主席树+切比雪夫距离转曼哈顿距离

    2735: 世博会 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 124  Solved: 51[Submit][Status][Discuss] D ...

  8. LOJ 2555 「CTSC2018」混合果汁——主席树

    题目:https://loj.ac/problem/2555 二分答案,在可以选的果汁中,从价格最小的开始选. 按价格排序,每次可以选的就是一个前缀.对序列建主席树,以价格为角标,维护体积和.体积*价 ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

随机推荐

  1. 使用 Drools 和 JPA & Drools show case in docker hub

    使用 Drools 和 JPA 实现持续的实时数据分析https://www.ibm.com/developerworks/cn/java/j-drools5/index.html Drools - ...

  2. 13 Connectors: show contrast/oppistion

    1 "but" 和 "yet" 用来显示两个意思之间的对比关系.在写作中,当 "but" 和"yet" 将两个分句连为一 ...

  3. tomcat8.0部署启动

    http://tomcat.apache.org/download-80.cgi 打开命令行提示符窗口, 进入Tomcat安装目录, 进入bin目录下, 输入:service.bat install  ...

  4. day 7-5 守护线程

    一. 守护线程 无论是进程还是线程,都遵循:守护进程(线程)会等待主进程(线程)运行完毕后被销毁. 需要强调的是:运行完毕并非终止运行. 1.对主进程来说,运行完毕指的是主进程代码运行完毕. 2.对主 ...

  5. Day 4-7 -configparser模块

    此模块用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser. 常用方法: import configparser conf = configpar ...

  6. 金蝶CLOUD与EAS的区别

    1.金蝶K/3 WISE主要面向单体制造企业(主要是离散制造企业):2.金蝶K/3 Cloud主要面向业务类型单一(即主营业务单一)的.注重供应链与生产业务协同的.中小型(二层集团??)集团性企业(主 ...

  7. vue & iview

    vue & iview ui components https://codepen.io/webgeeker/pen/EJmQxQ https://www.iviewui.com/docs/g ...

  8. jmeter 启动报错:not able to find java executable or version

    1 运行cmd输入:java -version 查看 提示没有命令 2 查看环境变量path 3 执行 %JAVA_HOME% 提示找不到文件件 4 修改 文件夹名称 5 运行cmd java -ve ...

  9. 错误模块名称: KERNELBASE.dll错误

    今天在部署一个C/S程序的时候出了bug,日志都没有记载:本地调试当然是没问题的,所以不是代码问题,百度之发现KERNELBASE.dll这个文章说的比较靠谱,仔细研究了自己的配置文件后,果然是配置文 ...

  10. 四、docker compose

    docker compose可以方便我们快捷高效地管理容器的启动.停止以及重启等操作,和批量管理容器,它类似于linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比如用什 ...