BZOJ4719 NOIP2016天天爱跑步(线段树合并)
线段树合并的话这个noip最难题就是个裸题了。
注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 300010
int n,m,p[N],a[N],fa[N][],deep[N],ans[N],root[][N],cnt[]={},t=;
vector<int> op1[N],op2[N];
struct data{int to,nxt;
}edge[N<<];
struct data2{int l,r,x;
}tree[][N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k][])
{
fa[edge[i].to][]=k;
deep[edge[i].to]=deep[k]+;
dfs(edge[i].to);
}
}
int lca(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
for (int j=;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
if (x==y) return x;
for (int j=;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
return fa[x][];
}
int merge(int x,int y,int l,int r,int p)
{
if (!x||!y) return x|y;
if (l==r) {tree[p][x].x+=tree[p][y].x;return x;}
int mid=l+r>>;
tree[p][x].l=merge(tree[p][x].l,tree[p][y].l,l,mid,p);
tree[p][x].r=merge(tree[p][x].r,tree[p][y].r,mid+,r,p);
return x;
}
void ins(int &k,int x,int l,int r,int v,int p)
{
if (!k) k=++cnt[p];
if (l==r) {tree[p][k].x+=v;return;}
int mid=l+r>>;
if (x<=mid) ins(tree[p][k].l,x,l,mid,v,p);
else ins(tree[p][k].r,x,mid+,r,v,p);
}
int query(int k,int l,int r,int x,int p)
{
if (!k) return ;
if (l==r) return tree[p][k].x;
int mid=l+r>>;
if (x<=mid) return query(tree[p][k].l,l,mid,x,p);
else return query(tree[p][k].r,mid+,r,x,p);
}
void getans(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k][])
{
getans(edge[i].to);
root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
}
for (int i=;i<op1[k].size();i++)
if (op1[k][i]>) ins(root[][k],op1[k][i],,n<<,,);
else ins(root[][k],-op1[k][i],,n<<,-,);
for (int i=;i<op2[k].size();i++)
if (op2[k][i]>) ins(root[][k],op2[k][i],,n<<,,);
else ins(root[][k],-op2[k][i],,n<<,-,);
ans[k]+=query(root[][k],,n<<,deep[k]+a[k],)+query(root[][k],,n<<,deep[k]-a[k]+n,);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4719.in","r",stdin);
freopen("bzoj4719.out","w",stdout);
#endif
n=read(),m=read();
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
fa[][]=;dfs();
for (int j=;j<;j++)
for (int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),l=lca(x,y);
if (l!=x) op1[x].push_back(deep[x]),op1[l==?:fa[l][]].push_back(-deep[x]);
if (l!=y) op2[y].push_back(deep[l]*-deep[x]+n),op2[l==x?(l==?:fa[l][]):l].push_back(deep[x]-deep[l]*-n);
if (l==x&&l==y&&a[l]==) ans[l]++;
}
getans();
for (int i=;i<=n;i++) printf("%d ",ans[i]);
return ;
}
BZOJ4719 NOIP2016天天爱跑步(线段树合并)的更多相关文章
- [NOIp2016]天天爱跑步 线段树合并
[NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...
- NOIP2016 天天爱跑步 线段树合并_桶_思维题
竟然独自想出来了,好开心 Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r&q ...
- 2018.08.09 bzoj4719: [Noip2016]天天爱跑步(树链剖分)
传送门 话说开始上文化课之后写题时间好少啊. 这道题将一个人的跑步路线拆成s->lca,lca->t,然后对于第一段上坡路径要经过的点,当前这个人能对它产生贡献当且仅当dep[s]-dep ...
- BZOJ4719 [Noip2016]天天爱跑步
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并
题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...
- LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)
题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...
- [NOIP2016 DAY1 T2]天天爱跑步-[差分+线段树合并][解题报告]
[NOIP2016 DAY1 T2]天天爱跑步 题面: B[NOIP2016 DAY1]天天爱跑步 时间限制 : - MS 空间限制 : 565536 KB 评测说明 : 2s Description ...
- [NOIP2016]天天爱跑步(树上差分+线段树合并)
将每个人跑步的路径拆分成x->lca,lca->y两条路径分别考虑: 对于在点i的观察点,这个人(s->t)能被观察到的充要条件为: 1.直向上的路径:w[i]=dep[s]-dep ...
- 洛谷P1600 天天爱跑步(线段树合并)
小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...
随机推荐
- Cache-Aside模式
Cache-Aside 该模式是从数据仓库中将数据加载到缓存中,从而提高访问速度的一种模式.该模式可以有效的提高性能,同时也能一定程度上保证缓存中的数据和数据仓库中的数据的一致性,和同步数据到数据仓库 ...
- SQLite3日期与时间,常见函数
SQLite3日期与时间,常见函数 import sqlite3 #con = sqlite3.connect('example.db') con = sqlite3.connect(":m ...
- 【转载】C/C++杂记:深入虚表结构
原文:C/C++杂记:深入虚表结构 1. 虚表与“虚函数表” 在“C/C++杂记:虚函数的实现的基本原理”一文中曾提到“虚函数表”的概念,只是为了便于理解,事实是:虚函数表并不真的独立存在,它只是虚表 ...
- 通知的多线程问题 iOS
发送通知在子线程,接受也在子线程.如果子线程操作UI,会打印一推日志,告诉我们应该主线程操作.
- rem自适应布局
rem自适应原理 rem是根据html的font-size大小来变化,正是基于这个出发,我们可以在每一个设备下根据设备的宽度设置对应的html字号,从而实现了自适应布局.更多介绍请看这篇文章:rem是 ...
- Intellij IDEA破解激活
本文使用破解补丁激活Intellij IDEA 第一步:下载破解补丁(http://idea.lanyus.com/) 第二步:将下载好的补丁放置磁盘的任意位置,下面是我放置的位置 第三步:打开Int ...
- Charles连接苹果及JSON乱码情况解决
1. Charles的JSON乱码情况解决: 点击Charles界面上的help—SSL proxying—install Charles Root Certificate,将证书安装到[受信任的根 ...
- Iterable/Iterator傻傻分不清
区别可迭代对象和迭代器 1.判断是否可以迭代 from collections import Iterabledef fid(times): n = 0 a , b = 0,1 while n < ...
- Jmeter如何做接口测试
最近在学习Jmeter,记录下来,与大家分享. 1. 打开Jmeter,我用的是5.0版本,打开后如下图所示: 2. 右键测试计划,添加 - 线程(用户) - 线程组,如下如图所示: 3. 右键线程组 ...
- 那些年安装Appium遇到的坑
安装appium以及相关的总体记录 1 主要流程是参照这个来 https://www.cnblogs.com/wangyinghao/p/5780151.html 细节参考虫师的博客 http ...