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 ...
随机推荐
- PostgreSQL 使用 LDAP 认证方式
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页 回到顶级页面:PostgreSQL索引页 [作者 高健@博客园 luckyjackgao@gmail. ...
- Qt 信号槽传递自定义结构体
Qt 在信号和槽中使用自己定义的结构体
- python全栈开发-前方高能-内置函数2
python_day_15 一.今日主要内容 1. lambda 匿名函数 语法: lambda 参数:返回值 不能完成复杂的操作 2. sorted() 函数 排序. 1. 可迭代对象 2. key ...
- Selenium2+python自动化-xpath定位语法
前言 在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语 ...
- Python range() 函数用法
函数语法 range(start, stop[, step]) 参数说明: start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: ...
- linux命令提示符设置
变成绿色 [root@localhost /usr/local]#vim /root/.bashrc # .bashrc # User specific aliases and functions a ...
- JAVA学习笔记--数组初始化
JAVA中,数组只是相同类型的.用一个标识符名称封装到一起的一个对象序列或基本类型数据序列.数组通过方括号下标操作符[]来定义和使用,要定义一个数组只需在类型名后面加上一个方括号即可,如: int[] ...
- 机器学习之决策树(ID3)算法
最近刚把<机器学习实战>中的决策树过了一遍,接下来通过书中的实例,来温习决策树构造算法中的ID3算法. 海洋生物数据: 不浮出水面是否可以生存 是否有脚蹼 属于鱼类 1 是 是 是 2 ...
- 阿里IPO法律咨询费达1580万美元 为Facebook六倍
据路透社报道,阿里巴巴集团周五在 IPO (首次公开招股)更新文件中披露,将向美国盛信律师事务所(Simpson Thacher)以及其他为 IPO 提供咨询服务的律师事务所支付 1580 万美元的法 ...
- KETTLE:mongdb与mysql互传数据
注:部分内容引用了 http://blog.sina.com.cn/s/blog_4ac9f56e0101g881.html 1.mongodb传数据到mysql 1)在kettle中,mongodb ...