题面

这题有点意思

转化问题,我们把询问区间的点到根链加,再查询询问点到根的权值和就是每个询问的答案。

然后如果你数据结构没学傻只需要差分一下就可以扫一遍出解了

 #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的更多相关文章

  1. [LNOI 2014]LCA

    Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. ...

  2. 【LNOI 2014】 LCA

    [题目链接] 点击打开链接 [算法] 考虑求lca(x,y)的深度 我们可以将从根到x路径上的点都打上标记,然后,询问y到根上路径的权值和 那么,求sigma(depth(lca(i,z)))(l & ...

  3. [Codevs1519]过路费解题报告|最小生成树|LCA

    在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...

  4. bzoj 4012: [HNOI2015]开店

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

  5. [GXOI/GZOI2019]旧词

    很像LNOI 2014 LCA那道题. 同样的套路,离线以后直接扫描线. k=1的话就是原题. 考虑一般情况. 原本的做法是对x到根的这条链做一下区间+1操作,目的是为了是的在深度为i的位置得到的贡献 ...

  6. POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】

    <题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...

  7. POJ 1330 Nearest Common Ancestors (模板题)【LCA】

    <题目链接> 题目大意: 给出一棵树,问任意两个点的最近公共祖先的编号. 解题分析:LCA模板题,下面用的是树上倍增求解. #include <iostream> #inclu ...

  8. 交通运输线(LCA)

    题目大意: 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市 ...

  9. [hdu3078]Network(LCA+排序)

    题意:维护树上两点之间的最短路径,其一,将点a的值变为b,其二,求路径上第k大的值. 解题关键:LCA+sort 复杂度:$O(qn\log n + n\log n)$ 数据弱不怪我 //#pragm ...

随机推荐

  1. 20155321 《网络攻防》 Exp2 后门原理与实践

    20155321 <网络攻防> Exp2 后门原理与实践 实验内容 例举你能想到的一个后门进入到你系统中的可能方式? 我觉得人们在平时上网的时候可能会无意识地点击到一些恶意的网站,这些网站 ...

  2. 【php增删改查实例】 第三节 - mysql 建表

    这一节,来给数据库中添加一些测试数据. 登陆mysql: 找到%xampp%\mysql\bin 目录, 在此处打开命令窗口,用root用户登陆mysql 用户表建表sql: CREATE TABLE ...

  3. noip 提高组 2010

    T1:机器翻译 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英 ...

  4. TMS320VC5509的MCBSP配置成SPI模式通信

    1. 首先是把MCBSP的配置 其次是时钟停止模式的配置,关闭大同小异 SPI有4中模式,怎么根据上面的寄存器选择哪种模式?下面展示了其中两种,CLKXP=1的时候有另外两种,暂时不整出来了 2. 代 ...

  5. redis见解

    http://blog.csdn.net/zhiguozhu/article/details/50517527Redis原生session与redis中的session区别原生session在服务器上 ...

  6. Flask学习-Flask基础之WSGI

    一.WSGI为什么会出现? 在学习一个东西之前,我们肯定想知道:它为什么会出现?那么,WSGI为什么会出现呢? 我们知道,部署一个web应用,经常需要使用nginx.apache或者IIS等web服务 ...

  7. Js_获取当前日期时间

    一.获取当前时间 new Date()方法---------得到结果是当前电脑时间如2011-11-6,10:07 二.获取有个固定的时间方法---------var endtime=new Date ...

  8. 机器视觉及图像处理系列之二(C++,VS2015)——图像级的人脸识别(1)

    接上一篇,一切顺利的话,你从github上clone下来的整个工程应该已经成功编译并生成dll和exe文件了:同时,ImageMagic程序亦能够打开并编辑图像了,如此,证明接下来的操练你不会有任何障 ...

  9. 通过sqli-labs学习sql注入——基础挑战之less1

    环境准备: Phpstudy  (PHP+Apache+Mysql) Sql-lab 首先了解下基础知识: URL编码: 因为在浏览器中,当我们访问一个网址的时候,浏览器会自动将用户输入的网址进行UR ...

  10. 互评Final版本——可以低头,但没必要——取件帮

    基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题; (1)N(Need,需求) 当今大部分在校学生由于各种原因懒于亲自去取快递,而总麻烦身边人也不是长久之计.而有些同学需 ...