解题:LNOI 2014 LCA
这题有点意思
转化问题,我们把询问区间的点到根链加,再查询询问点到根的权值和就是每个询问的答案。
然后如果你数据结构没学傻只需要差分一下就可以扫一遍出解了
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define vpii vector<pair<int,int> >
#define vpit vector<pair<int,int> >::iterator
using namespace std;
const int N=,M=,mod=;
int p[N],noww[M],goal[M],val[M],laz[M],siz[N];
int far[N],dep[N],imp[N],dfn[N],top[N],ans[N];
int n,q,t1,t2,t3,cnt,tot; vpii lp[N],rp[N];
void Add(int &x,int y)
{
x+=y;
if(x>=mod) x-=mod;
}
void Link(int f,int t)
{//printf("Link %d with %d",f,t);
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
noww[++cnt]=p[t];
goal[cnt]=f,p[t]=cnt;
}
void Release(int nde,int l,int r)
{
if(laz[nde])
{
int mid=(l+r)/,ls=*nde,rs=*nde+,&lz=laz[nde];
val[ls]+=lz*(mid-l+),laz[ls]+=lz;
val[rs]+=lz*(r-mid),laz[rs]+=lz,lz=;
}
}
void Change(int nde,int l,int r,int ll,int rr,int tsk)
{
if(l>rr||r<ll)
return ;
else if(l>=ll&&r<=rr)
val[nde]+=tsk*(r-l+),laz[nde]+=tsk;
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; Release(nde,l,r);
Change(ls,l,mid,ll,rr,tsk),Change(rs,mid+,r,ll,rr,tsk);
val[nde]=val[ls]+val[rs];
}
}
int Query(int nde,int l,int r,int ll,int rr)
{
if(l>rr||r<ll)
return ;
else if(l>=ll&&r<=rr)
return val[nde];
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; Release(nde,l,r);
return Query(ls,l,mid,ll,rr)+Query(rs,mid+,r,ll,rr);
}
}
void DFS(int nde,int fth,int dth)
{
int tmp=;
siz[nde]=,far[nde]=fth,dep[nde]=dth;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde,dth+);
siz[nde]+=siz[goal[i]];
if(siz[goal[i]]>tmp)
tmp=siz[goal[i]],imp[nde]=goal[i];
}
}
void Decompose(int nde,int tpp)
{
dfn[nde]=++tot,top[nde]=tpp;
if(imp[nde])
{
Decompose(imp[nde],tpp);
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=imp[nde]&&goal[i]!=far[nde])
Decompose(goal[i],goal[i]);
}
}
void Chain_Change(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Change(,,n,dfn[top[x]],dfn[x],v),x=far[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
Change(,,n,dfn[x],dfn[y],v);
}
int Chain_Query(int x,int y)
{
int ret=;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=Query(,,n,dfn[top[x]],dfn[x]),x=far[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ret+=Query(,,n,dfn[x],dfn[y]); return ret;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
scanf("%d",&t1),Link(t1+,i);
for(int i=;i<=q;i++)
{
scanf("%d%d%d",&t1,&t2,&t3);
lp[t1].push_back(make_pair(i,t3+));
rp[t2+].push_back(make_pair(i,t3+));
}
DFS(,,),Decompose(,);
for(int i=;i<=n;i++)
{
Chain_Change(,i,);
for(vpit it=lp[i].begin();it!=lp[i].end();it++)
ans[it->first]-=Chain_Query(,it->second);//,printf("%d-=%d\n",it->first,Chain_Query(1,it->second));
for(vpit it=rp[i].begin();it!=rp[i].end();it++)
ans[it->first]+=Chain_Query(,it->second);//,printf("%d+=%d\n",it->first,Chain_Query(1,it->second));
}
for(int i=;i<=q;i++)
printf("%d\n",ans[i]%mod);
return ;
}
解题:LNOI 2014 LCA的更多相关文章
- [LNOI 2014]LCA
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. ...
- 【LNOI 2014】 LCA
[题目链接] 点击打开链接 [算法] 考虑求lca(x,y)的深度 我们可以将从根到x路径上的点都打上标记,然后,询问y到根上路径的权值和 那么,求sigma(depth(lca(i,z)))(l & ...
- [Codevs1519]过路费解题报告|最小生成树|LCA
在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...
- bzoj 4012: [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- [GXOI/GZOI2019]旧词
很像LNOI 2014 LCA那道题. 同样的套路,离线以后直接扫描线. k=1的话就是原题. 考虑一般情况. 原本的做法是对x到根的这条链做一下区间+1操作,目的是为了是的在深度为i的位置得到的贡献 ...
- POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】
<题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...
- POJ 1330 Nearest Common Ancestors (模板题)【LCA】
<题目链接> 题目大意: 给出一棵树,问任意两个点的最近公共祖先的编号. 解题分析:LCA模板题,下面用的是树上倍增求解. #include <iostream> #inclu ...
- 交通运输线(LCA)
题目大意: 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市 ...
- [hdu3078]Network(LCA+排序)
题意:维护树上两点之间的最短路径,其一,将点a的值变为b,其二,求路径上第k大的值. 解题关键:LCA+sort 复杂度:$O(qn\log n + n\log n)$ 数据弱不怪我 //#pragm ...
随机推荐
- python变量名感悟
我感悟的是python的变量名其实就可以理解为C/C++中的指针! 1.python的变量在使用之前必须赋值,就像指针在使用之前不能为空. 2.python的内存可以用del释放,C++可以用dele ...
- Linux 平台和 Windows平台下 Unicode与UTF-8互转
Windows: unsigned char * make_utf8_string(const wchar_t *unicode) { , index = , out_index = ; unsign ...
- cocos2d-x学习记录3——CCTouch触摸响应
游戏不同于影音,强交互性是其一大特色,在游戏中主要体现为接受用户的输入并响应.智能手机触摸是其重要的输入方式. 在cocos2d-x中,触摸分为单点触摸和多点触摸. 单点触摸:主要继承CCTarget ...
- Django实现websocket完成实时通讯、聊天室、在线客服等
一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...
- SpringMVC RestTemplate的几种请求调用
转载:https://blog.csdn.net/ThinkingLink/article/details/45366777 1.用统一的方法模板进行四种请求:POST,PUT,DELETE,GET ...
- effective c++ 笔记 (49-52)
//---------------------------15/04/27---------------------------- //#49 了解new-handler的行为 { /* 1:在o ...
- Java中Class类详解、用法及泛化
Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方 ...
- 3dmax2020下载安装3dmax2020破解中文版下载安装
3dmax在室内设计.建筑设计领域是最专业的效果图制作软件,也是在游戏动画等领域中在场景方面最专业的软件,目前最新3dmax2020版本已出,我分享亲测好用的软件包,拿走不谢! 3dmax2020安装 ...
- numpy 初识(三)
基本运算 exp: e sqrt:开放 floor:向下取整 ravel:矩阵拉成一个向 T:转置(行和列变换) 改变形状: resize: 更改其形状(返回值为None)a.resize(6,2) ...
- Catlike学习笔记(1.3)-使用Unity画更复杂的3D函数图像
第三篇来了-今天去参加了 Unite 2018 Berlin,感觉就是....非常困...回来以后稍微睡了下清醒了觉得是时候认真学习下了,不过讲的很多东西都是还没有发布或者只有 Preview 的版本 ...