解题: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 ...
随机推荐
- WPF Style
<Application x:Class="WzlyTool.App" xmlns="http://schemas.microsoft.com/winfx/20 ...
- 2017-2018-2 20155234『网络对抗技术』Exp5:MSF基础应用
攻击MS08-067安全漏洞--WindowsXP 在kali输入msfconsole进入控制台,依次输入指令 第一次很遗憾失败了 发现是防火墙没关重新来过成功 攻击MS11-050安全漏洞--IE7 ...
- MFC CHotKeyCtrl控件
知识点: CHotKeyCtrl控件 获取热键数据 注册热键 响应热键事件 一.CHotKeyCtrl控件 void SetHotKey( WORD wVirtualKeyCode, WORD wMo ...
- 《无所不能的JavaScript编程系列:setTimeout 简笔》
前言:问题引出 JavaScript中会经常用到setTimeout来推迟一个函数的执行,如: setTimeout(function(){alert("Hello World") ...
- c语言数字图像处理(二):图片放大与缩小-双线性内插法
图像内插 假设一幅大小为500 * 500的图像扩大1.5倍到750 * 750,创建一个750 * 750 的网格,使其与原图像间隔相同,然后缩小至原图大小,在原图中寻找最接近的像素(或周围的像素) ...
- 12.22daily_scrum
今天是我们小组M2阶段开始一周结束,各项工作进入一个阶段性的总结过程,悬浮窗的设计也已经告一段落进入调试的阶段,新的工作任务有了添加,即滑锁密码的加入,更好地加深了用户体验性,软件的可用性也进一步加强 ...
- M1事后分析报告--We have power to change the origin state
M1事后分析报告 设计与实现 我们发的软件解决的问题?是否满足后面小组的要求?是否能够完全拟合前期目标? 答: 前期我们的软件完成量并不是特别让人满意,我们组在完成这些任务量之后,发现有很多地方是在做 ...
- LeetCode 638 Shopping Offers
题目链接: LeetCode 638 Shopping Offers 题解 dynamic programing 需要用到进制转换来表示状态,或者可以直接用一个vector来保存状态. 代码 1.未优 ...
- Mysql设置允许外网访问(图文)
1.打开mysql.exe(MySQL Command Line Client),输入密码 2.输入:use mysql; 3.查询host输入: select user,host from user ...
- 开源通用爬虫框架YayCrawler-运行与调试
本节我将向大家介绍如何运行与调试YayCrawler.该框架是采用SpringBoot开发的,所以可以通过java –jar xxxx.jar的方式运行,也可以部署在tomcat等容器中运行. 首先 ...