luogu P1600 天天爱跑步
1A此题暴祭
(下面记点\(x\)深度为\(de_x\),某个时间点记为\(w_x\))
首先,每条路径是可以拆成往上和往下两条路径的
对于往上的路径,假设有个人往上跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x+de_x=w_y+de_y\)
对于往下的路径,假设有个人往下跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x-de_x=w_y-de_y\)
所以对于每个点开两个线段树,每个下表存\(w_x+de_x\)或\(w_x-de_x\)的点的个数,对于每条路径(x,y),记\(len\)为路径长度(结束时间点),\(mid\)为到达\(lca\)的时间,在\(x\)的第一个线段树的\(de_x\)处+1,在\(lca\)的第一个线段树的\(mid+de_{lca}\)处-1,在y的第二个线段树的\(len-de_y+n\)处+1,在\(fa_{lca}\)的第二个线段树的\(mid-1-de_{fa_{lca}}+n\)处-1(不能出现负下标).dfs整棵树,把\(x\)所有儿子的线段树并起来,然后这个点的答案就是第一棵线段树的\(w_x+de_x\)加第二棵线段树的\(w_x-de_x+n\)的值
我太傻了,这两颗线段树可以分开处理的,我放在一起处理了,空间爆炸,bzoj就过不去了qwq
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5)
using namespace std;
const int N=300000+10;
il LL rd()
{
  LL x=0,w=1;char ch=0;
  while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
il void add(int x,int y)
{
  ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
  ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,m,w[N],an[N],fa[N],sz[N],de[N],son[N],top[N];
void dfs1(int x)
{
  sz[x]=1;
  for(int i=hd[x];i;i=nt[i])
    {
      int y=to[i];
      if(y==fa[x]) continue;
      fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
      if(sz[son[x]]<sz[y]) son[x]=y;
    }
}
void dfs2(int x,int ntp)
{
  top[x]=ntp;
  if(son[x]) dfs2(son[x],ntp);
  for(int i=hd[x];i;i=nt[i])
    {
      int y=to[i];
      if(y==fa[x]||y==son[x]) continue;
      dfs2(y,y);
    }
}
il int glca(int x,int y)
{
  while(top[x]!=top[y])
    {
      if(de[top[x]]<de[top[y]]) swap(x,y);
      x=fa[top[x]];
    }
  return de[x]<de[y]?x:y;
}
struct sgtree
{
  int s[(N*3)*20],ch[(N*3)*20][2],rt[N],tt;
  sgtree(){tt=0;}
  il void inst(int o1,int o2,int x,int dt)
  {
    int l=1,r=n+n;
    s[o1]=s[o2]+dt;
    while(l<r)
      {
        int mid=(l+r)>>1;
        if(x<=mid)
          {
            ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
            o1=ch[o1][0],o2=ch[o2][0];
            r=mid;
          }
        else
          {
            ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
            o1=ch[o1][1],o2=ch[o2][1];
            l=mid+1;
          }
        s[o1]=s[o2]+dt;
      }
  }
  int merge(int o1,int o2)
  {
    if(!o1||!o2) return o1+o2;
    int o=++tt;
    s[o]=s[o1]+s[o2];
    ch[o][0]=merge(ch[o1][0],ch[o2][0]);
    ch[o][1]=merge(ch[o1][1],ch[o2][1]);
    return o;
  }
  int quer(int o,int l,int r,int lx)
  {
    if(!o) return 0;
    if(l==r) return s[o];
    int mid=(l+r)>>1;
    if(lx<=mid) return quer(ch[o][0],l,mid,lx);
    else return quer(ch[o][1],mid+1,r,lx);
  }
}S,T;
il void dfs3(int x)
{
  for(int i=hd[x];i;i=nt[i])
    {
      int y=to[i];
      if(y==fa[x]) continue;
      dfs3(y),S.rt[x]=S.merge(S.rt[x],S.rt[y]),T.rt[x]=T.merge(T.rt[x],T.rt[y]);
    }
  an[x]=S.quer(S.rt[x],1,n+n,w[x]+de[x])+T.quer(T.rt[x],1,n+n,w[x]-de[x]+n);
}
int main()
{
  n=rd(),m=rd();
  for(int i=1;i<n;i++) add(rd(),rd());
  de[1]=1,dfs1(1),dfs2(1,1);
  for(int i=1;i<=n;i++) w[i]=rd();
  while(m--)
    {
      int x=rd(),y=rd(),lca=glca(x,y),lth=de[x]+de[y]-(de[lca]<<1),mid=lth-de[y]+de[lca],la;
      la=S.rt[x],S.rt[x]=++S.tt,S.inst(S.rt[x],la,de[x],1);
      la=S.rt[lca],S.rt[lca]=++S.tt,S.inst(S.rt[lca],la,de[lca]+mid,-1);
      la=T.rt[y],T.rt[y]=++T.tt,T.inst(T.rt[y],la,lth-de[y]+n,1);
      la=T.rt[fa[lca]],T.rt[fa[lca]]=++T.tt,T.inst(T.rt[fa[lca]],la,mid-1-de[fa[lca]]+n,-1);
    }
  dfs3(1);
  for(int i=1;i<=n;i++) printf("%d ",an[i]);
  return 0;
}
												
											luogu P1600 天天爱跑步的更多相关文章
- [NOIP 2016D2T2/Luogu P1600] 天天爱跑步  (LCA+差分)
		
待填坑 Code //Luogu P1600 天天爱跑步 //Apr,4th,2018 //树上差分+LCA #include<iostream> #include<cstdio&g ...
 - [luogu]P1600 天天爱跑步[LCA]
		
[luogu]P1600 [NOIP 2016]天天爱跑步 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上 ...
 - 洛谷P1600 天天爱跑步(线段树合并)
		
小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...
 - P1600 天天爱跑步[桶+LCA+树上差分]
		
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵 ...
 - Luogu:P1600   天天爱跑步
		
来一发清新的80行 树剖 $LCA$ + 树上差分 题解. -----from Judge 本题题意大概是给出一棵 n 个节点的树以及 m 条有向路径, 并且每个点 i 都有一个权值 $w[i]$,如 ...
 - 洛谷 P1600 天天爱跑步
		
https://www.luogu.org/problemnew/show/P1600 (仅做记录) 自己的假方法: 每一次跑从a到b:设l=lca(a,b)对于以下产生贡献: a到l的链上所有的点( ...
 - 洛谷P1600 天天爱跑步——树上差分
		
题目:https://www.luogu.org/problemnew/show/P1600 看博客:https://blog.csdn.net/clove_unique/article/detail ...
 - 洛谷P1600 天天爱跑步
		
天天放毒... 首先介绍一个树上差分. 每次进入的时候记录贡献,跟出来的时候的差值就是子树贡献. 然后就可以做了. 发现考虑每个人的贡献有困难. 于是考虑每个观察员的答案. 把路径拆成两条,以lca分 ...
 - P1600 天天爱跑步
		
lca真心不太会,这里只介绍60分做法,100的太难辣简单了就不介绍了 n<=1000 zz回溯爆搜 S[i]全部相等 这dfs序都不用lca的,2333,差分,然后输出判断一下是否是0(1到i ...
 
随机推荐
- 【Linux】工作管理
			
在进行工作管理的行为中,其实每个工作都是目前bash的子进程,即彼此间是有相关性的.我们无法以job control的方式由tty1的环境去管理tty2的bash 当只有一个终端时,可以出现提示符让你 ...
 - mysql DDL&DML 语言
			
DDL:数据定义语言 CREATE, ALTER, DROP CREATE相关的常用命令: CREATE DATABASECREATE EVENTCREATE FUNCTIONCREATE FUNCT ...
 - MT【13】三角函数求范围
			
解答:AB显然正确,C中$a$取0时,解为三个,C 错误.我们主要看一下D 评:这里提供了一个处理$sin^2xcosx$的常见方法:平方,单变量后用算术几何不等式.
 - 2.9 C++使用默认参数的构造函数
			
总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...
 - python 和 scikit-learn 实现垃圾邮件过滤
			
文本挖掘(Text Mining,从文字中获取信息)是一个比较宽泛的概念,这一技术在如今每天都有海量文本数据生成的时代越来越受到关注.目前,在机器学习模型的帮助下,包括情绪分析,文件分类,话题分类,文 ...
 - NOI2018退役记
			
NOI2018退役记 终于我也退役了-- Day0 高中毕业前最后一次坐飞机了--在机场干什么呢?当然是打元气打元气打元气.下飞机干什么呢?当然是打元气打元气打元气. 有接机服务,大巴上有个导游,又向 ...
 - 洛谷P1247 取火柴游戏
			
经典NIM游戏. 取XOR和即可. 注意输出方案时,找到大于异或和sum的,变为a[i] ^ sum即可. #include <cstdio> ; int a[N]; int main() ...
 - 跟我一起使用electron搭建一个文件浏览器应用吧(二)
			
这个文件浏览器应用可以具备以下两种功能噢- This file browser application can have the following two functions. 一:用户浏览文件夹和 ...
 - Mysq中的流程控制语句的用法
			
这篇博客主要是总结一下Mysq中的流程控制语句的用法,主要是:CASE,IF,IFNULL,NULLIF 1.case CASE value WHEN [compare-value] THEN res ...
 - 设置 webstorm 对 .vue 高亮
			
1. 首先安装vue插件,安装方法: setting --> plugin ,点击plugin,在内容部分的左侧输入框输入vue,会出现两个关于vue的插件,点击安装即可.安装完成后,就可 ...