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 ...
随机推荐
- 【LG4585】[FJOI2015]火星商店问题
[LG4585][FJOI2015]火星商店问题 题面 bzoj权限题 洛谷 \(Notice:\) 关于题面的几个比较坑的地方: "一天"不是一个操作,而是有0操作就相当于一天开 ...
- C++从静态对象的初始化顺序理解static关键字
问题 首先考虑一个全局变量的初始化顺序问题 在头文件1中: extern int b; ; 在头文件2中: extern int a; ; 源文件中包含了头文件1和头文件2,这种情况下a和b可能的值是 ...
- No.03---Vue学习之路之模块化组织
前两篇讲解了一下 Vuex 的基本使用方法,可是在实际项目中那么写肯定是不合理的,如果组件太多,不可能把所有组件的数据都放到一个 store.js 中的,所以就需要模块化的组织 Vuex,首先看一下 ...
- HPUX修改disk实例号--11.31only
有时由于一些原因或者用户的要求,需要修改Disk的实例号,这里简单介绍如何手工进行修改. 在修改之前需要做一些准备工作,即先将stale状态的设备文件清理掉,具体步骤如下: 使用ioscan命令列出s ...
- Educational Codeforces Round 63 D. Beautiful Array
D. Beautiful Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 17 Tips For Writing An Excellent Email Subject Line
Out of the billions of emails that are sent every day, how can you make sure that yours stands out? ...
- 20181113-3 Beta阶段贡献分配规则
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2382 在新成员加入后,我们经过商讨,决定沿用alpha阶段贡献分分配规则 ...
- 欢迎来怼--第二十三次Scrum会议
一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/11 17:20~17:55,总计35min. 地 ...
- Ubuntu16.04安装oracle-java8-installer
本篇博客参考 1. 安装默认JRE/JDK 更新 sudo apt-get update 检查是否安装了Java java -version 如果返回The program java can be f ...
- 【分层最短路】Joyride
http://codeforces.com/gym/101873 C 多开一维状态记录时间,d[i][t] = 经过时间t走到节点i的最小花费 每一个状态分别向"原地等待"与&qu ...