如果没有时间的限制,这题就是对每个点iii,求经过iii的路径数,用树上差分解决即可:

枚举路径x→y{x\to y\{x→y{

a[x]+=1;a[y]+=1;a[x]+=1;a[y]+=1;a[x]+=1;a[y]+=1;
a[lca(x,y)]−=1;a[fa[lca(x,y)]]−=2;a[lca(x,y)]-=1;a[fa[lca(x,y)]]-=2;a[lca(x,y)]−=1;a[fa[lca(x,y)]]−=2;

}\}}

枚举点i{i\{i{

经过iii的路径数 = 以iii为根的子树中aaa的和

}\}}

(用树状数组实现)

考虑加上时间限制怎么做:

我们把每条路径x→yx\to yx→y拆成上行段和下行段。

  • 若点iii在x→yx\to yx→y的上行段上,
    iii点的观察员看到从xxx出发跑到yyy的玩家,当且仅当
    dep[x]−dep[i]=w[i]dep[x]-dep[i]=w[i]dep[x]−dep[i]=w[i]即dep[i]+w[i]=dep[x]dep[i]+w[i]=dep[x]dep[i]+w[i]=dep[x]

  • 若点iii在x→yx\to yx→y的下行段上,
    iii点的观察员看到从xxx出发跑到yyy的玩家,当且仅当
    dep[x]+dep[y]−2dep[lca(x,y)]−(dep[y]−dep[i])=w[i]dep[x]+dep[y]-2dep[lca(x,y)]-(dep[y]-dep[i])=w[i]dep[x]+dep[y]−2dep[lca(x,y)]−(dep[y]−dep[i])=w[i]
    即dep[i]−w[i]=2dep[lca(x,y)]−dep[x]dep[i]-w[i]=2dep[lca(x,y)]-dep[x]dep[i]−w[i]=2dep[lca(x,y)]−dep[x]

对于路径x→yx\to yx→y,我们将其拆成 上行段p:x→lca(x,y)p:x\to lca(x,y)p:x→lca(x,y)在xxx方向上的儿子,下行段q:lca(x,y)→yq:lca(x,y)\to yq:lca(x,y)→y,并记v[p]=dep[x]v[p]=dep[x]v[p]=dep[x],v[q]=2dep[lca(x,y)]−dep[x]v[q]=2dep[lca(x,y)]-dep[x]v[q]=2dep[lca(x,y)]−dep[x]

对于点iii,我们记vp[i]=dep[i]+w[i]v_p[i]=dep[i]+w[i]vp​[i]=dep[i]+w[i],vq[i]=dep[i]−w[i]v_q[i]=dep[i]-w[i]vq​[i]=dep[i]−w[i]

那么iii点的观察员看到的玩家数 = ∑\sum∑经过iii且满足v[p]=vp[i]v[p]=v_p[i]v[p]=vp​[i]的上行段ppp的数量 + ∑\sum∑经过iii且满足v[q]=vq[i]v[q]=v_q[i]v[q]=vq​[i]的下行段qqq的数量

先把点按vp[i]v_p[i]vp​[i]排序,把上行段按v[p]v[p]v[p]排序,按树上差分的套路计算上行段的贡献。

再把点按vq[i]v_q[i]vq​[i]排序,把下行段按v[q]v[q]v[q]排序,按树上差分的套路计算下行段的贡献。

如此即可得到最终答案。

#include<iostream>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
const int N=1e6+10;
struct Edge{int v,nxt;
}edge[N<<1];
int n,m,w[N],cnt,head[N],ans[N];
int ind,dfn[N],siz[N],dep[N],fa[N][20];
struct Query{int nd,x;friend bool operator < (Query a,Query b){return a.x<b.x;}
}a[N<<1];
struct Data{int d,u,x;friend bool operator < (Data a,Data b){return a.x<b.x;}
}b[2][N];
int tot[2];
stack<Data> s;
void addedge(int u,int v){edge[++cnt].v=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
void dfs(int u){dfn[u]=++ind;siz[u]=1;for(int i=1;i<=19;i++)fa[u][i]=fa[fa[u][i-1]][i-1];for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].v;if(v==fa[u][0]) continue;fa[v][0]=u;dep[v]=dep[u]+1;dfs(v);siz[u]+=siz[v];}
}
int LCA(int u,int v){if(dep[u]<dep[v]) swap(u,v);int diff=dep[u]-dep[v];for(int i=19;i>=0;i--){if(diff&(1<<i)) u=fa[u][i];}if(u==v) return u;for(int i=19;i>=0;i--){if(fa[u][i]!=fa[v][i]){u=fa[u][i];v=fa[v][i];}}return fa[u][0];
}
int c[N];
int lowbit(int x){return x&(-x);}
void add(int x,int v){if(!x) return;for(int i=x;i<=n;i+=lowbit(i)) c[i]+=v;
}
int sum(int x){int res=0;for(int i=x;i;i-=lowbit(i)) res+=c[i];return res;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}dep[1]=1;dfs(1);for(int i=1;i<=n;i++){scanf("%d",&w[i]);a[i]=(Query){i,dep[i]+w[i]};a[i+n]=(Query){i,dep[i]-w[i]};}sort(a+1,a+n+1);sort(a+n+1,a+2*n+1);for(int i=1;i<=m;i++){int s,t,lca;scanf("%d%d",&s,&t);lca=LCA(s,t);if(s==lca){b[1][++tot[1]]=(Data){t,s,dep[s]};}else if(t==lca){b[0][++tot[0]]=(Data){s,t,dep[s]};}else{int son=s;for(int i=19;i>=0;i--){if(dep[fa[son][i]]>dep[lca]) son=fa[son][i];}b[0][++tot[0]]=(Data){s,son,dep[s]};b[1][++tot[1]]=(Data){t,lca,2*dep[lca]-dep[s]};}}sort(b[0]+1,b[0]+tot[0]+1);sort(b[1]+1,b[1]+tot[1]+1);int p=1;for(int i=1;i<=n;i++){if(a[i].x!=a[i-1].x){while(!s.empty()){Data tmp=s.top();s.pop();add(dfn[fa[tmp.u][0]],1);add(dfn[tmp.d],-1);}}for(;p<=tot[0]&&b[0][p].x<=a[i].x;p++){if(a[i].x!=a[i-1].x&&b[0][p].x==a[i].x){Data tmp=b[0][p];add(dfn[fa[tmp.u][0]],-1);add(dfn[tmp.d],1);s.push(tmp);}}ans[a[i].nd]+=sum(dfn[a[i].nd]+siz[a[i].nd]-1)-sum(dfn[a[i].nd]-1);}while(!s.empty()){Data tmp=s.top();s.pop();add(dfn[fa[tmp.u][0]],1);add(dfn[tmp.d],-1);}p=1;for(int i=n+1;i<=2*n;i++){if(a[i].x!=a[i-1].x){while(!s.empty()){Data tmp=s.top();s.pop();add(dfn[fa[tmp.u][0]],1);add(dfn[tmp.d],-1);}}for(;p<=tot[1]&&b[1][p].x<=a[i].x;p++){if(a[i].x!=a[i-1].x&&b[1][p].x==a[i].x){Data tmp=b[1][p];add(dfn[fa[tmp.u][0]],-1);add(dfn[tmp.d],1);s.push(tmp);}}ans[a[i].nd]+=sum(dfn[a[i].nd]+siz[a[i].nd]-1)-sum(dfn[a[i].nd]-1);}for(int i=1;i<=n;i++)printf("%d ",ans[i]);return 0;
}

[NOIP2016 提高组] 天天爱跑步(树上差分)相关推荐

  1. NOIP2016提高组 天天爱跑步

    (树上差分 + \(LCA\)) \(O(Mlog_2N)\) 调了两个小时,最后发现把\(lca\)里的\(y\)写成\(x\)了,当场去世. 首先下几个定义: \(dis[x]\) 为\(x\)到 ...

  2. 天天爱跑步——树上差分

    先来一道简化版: 关联点 2 • 给出一棵二叉树,每个点有点权 ?? • 如果 ? 在 ? 的左(右)子树中,且 ? 到 ? 的距离为 ??,则称 ? 为 ? 的左(右)关联点 • 求每个点的左.右关 ...

  3. 【NOIP2016提高组】天天爱跑步

    题目背景 NOIP2016 提高组 Day1 T2 题目描述 小 C 同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每 ...

  4. P1850 [NOIP2016 提高组] 换教室

    P1850 [NOIP2016 提高组] 换教室 题意: 有2n个课安排在n个时间段上,每个时间段上都有两个一样的课同时在不同地方上,起初牛牛被所有课都被安排在Ci上课,另一节课在Di上课.牛牛现在想 ...

  5. [NOIP2016 提高组] 愤怒的小鸟

    [NOIP2016 提高组] 愤怒的小鸟 题意: 有n只猪,给出猪的坐标(xi,yi),问最少用几个形如 y=ax^2+bx 的曲线可以保证所有猪在曲线上,满足a<0,a,b为实数 n<= ...

  6. #185. [NOIP2016 提高组] 蚯蚓题解

    #185. [NOIP2016 提高组] 蚯蚓题解 题目描述 本题中,我们将用符号 ⌊c⌋\lfloor c \rfloor⌊c⌋ 表示对 ccc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋= ...

  7. NOIP2016提高组 第一天第二题 天天爱跑步running 题解

    题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...

  8. BZOJ 4719--天天爱跑步(LCA差分)

    4719: [Noip2016]天天爱跑步 Time Limit: 40 Sec  Memory Limit: 512 MB Submit: 1464  Solved: 490 [Submit][St ...

  9. NOIP2016·洛谷·天天爱跑步

    初见安~这里是传送门:洛谷P1600 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打 ...

最新文章

  1. MySQL数据库开发常见问题及几点优化!
  2. Linux_《Linux命令行与shell脚本编程大全》第十八章学习总结
  3. 不同系统平台下Java默认的安装路径
  4. python打包的程序很大_Pyinstaller 打包以及pipenv 虚拟环境应用,以及打包出来程序太大的解决办法...
  5. 实例讲解——系统登录
  6. 带有Java 8,lambda表达式和Mockito-Java8附加组件的更紧凑的Mockito
  7. 从零开始学Axure原型设计(高级篇)
  8. 第七季4:网络telnet调试、海思proc文件系统调试接口
  9. Redis 持久化——RDB
  10. 线性表之顺序存储结构相关算法学习
  11. java数据结构编写二叉树_java 数据结构与算法 BinaryTree二叉树编写
  12. Gentle.NET笔记(二)-列表示例
  13. index()函数和match()函数联合使用案例
  14. abaqus质量缩放系数取值_ABAQUS中的质量缩放
  15. 玩转Lenovo Idea pad 的音效功能
  16. 固态硬盘(SSD) 和机 械硬盘(HDD) 优缺点比较
  17. 全球投资者聚焦阿里巴巴新零售:天猫力量定义商业未来
  18. ps中如何把图片变白底
  19. Restful-API设计最佳实战--Django播客系统(五)
  20. Leetcode刷题总结(三)

热门文章

  1. mysql安装版和解压版哪个好_红米k30pro变焦版和荣耀30pro哪个好-哪个更值得入手...
  2. python求解微分方程组_python – SymPy / SciPy:求解具有不同变量的常微分方程组...
  3. 软件构造学习笔记-第八周
  4. [Nginx]location 指令说明
  5. 高等数学下-赵立军-北京大学出版社-题解-练习9.3
  6. 蓝桥杯2015初赛-三羊献瑞-枚举
  7. 2020牛客国庆集训派对day2 F题 Java大数处理
  8. Seek the Name, Seek the Fame POJ - 2752 (理解KMP函数的失配)既是S的前缀又是S的后缀的子串
  9. Shader 坐标转换
  10. 【清华集训2014】Sum)(类欧几里得算法)