NOIP2016天天爱跑步

这题一看显然lca+树上差分,但是因为有w的限制不能直接加,所以考虑权值线段树合并,

每个选手的起点终点对于不同的节点的影响是不同的,这就非常麻烦了,但是可以发现无论如何他的深度是固定的,而对于一个节点i,能使他+1有如下两种情况:

1.dep[x]=dep[i]-w[i]

2.dep[x]=dep[i]+w[i]

于是对于一组s,t,求出他们的lca将路径分为两段,给s的dep[s]值加1,fa[lca]减1,t的2*dep[lca]-dep[s]加1,lca减1,

最后dfs线段树合并,对于一个节点x,查询对应线段树中dep[x]-w[x]+dep[x]+w[x]的个数,注意如果w[x]是0要除2(因为多加了一遍)。

有了“雨天的尾巴”的经验,这道题代码还是很好调的。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct edge
{int u,v,nxt;#define u(x) ed[x].u#define v(x) ed[x].v#define n(x) ed[x].nxt
}ed[300010];
int first[300010],num_e;
#define f(x) first[x]
int n,m,root;
int dep[300010],du[300010];
struct tree
{int ls,rs,l,r,sum;#define ls(x)  tr[x].ls#define rs(x)  tr[x].rs#define l(x)   tr[x].l#define r(x)   tr[x].r#define sum(x) tr[x].sum
}tr[10000010];
int cnt,T[300010];
void add(int &x,int y,int z,int l,int r)
{     if(!x){x=++cnt;l(x)=l,r(x)=r;}if(l==r){sum(x)+=z;return;}int mid=(l(x)+r(x))>>1;if(y<=mid)add(ls(x),y,z,l,mid);else      add(rs(x),y,z,mid+1,r);sum(x)=0;if(ls(x))sum(x)+=sum(ls(x));if(rs(x))sum(x)+=sum(rs(x));
}
int merge(int x,int y,int l,int r)
{if(!x||!y)return x+y;if(l==r){sum(x)+=sum(y);return x;}int mid=(l+r)>>1;ls(x)=merge(ls(x),ls(y),l,mid);rs(x)=merge(rs(x),rs(y),mid+1,r);sum(x)=sum(ls(x))+sum(rs(x));return x;
}
int ask(int x,int val,int l,int r)
{if(l==r){return sum(x);}int mid=(l+r)>>1;if(val<=mid)return ask(ls(x),val,l,mid);else        return ask(rs(x),val,mid+1,r);
}
int f[300010][21];
int LCA(int x,int y)
{if(x==y)return x;if(dep[x]>dep[y])swap(x,y);while(dep[x]<dep[y])for(int i=0;;i++)if(dep[f[y][i]]<dep[x]){y=f[y][i-1];break;}if(x==y)return x;while(f[x][0]!=f[y][0])for(int i=0;;i++)if(f[x][i]==f[y][i]){x=f[x][i-1],y=f[y][i-1];break;}return f[x][0];
}
void dfs(int x,int de,int fa)
{dep[x]=de;f[x][0]=fa;for(int i=f(x);i;i=n(i))dfs(v(i),de+1,x);
}
int ans[300010],w[300010];
void dfs2(int x)
{for(int i=f(x);i;i=n(i)){dfs2(v(i));T[x]=merge(T[x],T[v(i)],-n-1,n+1);}int t1=ask(T[x],dep[x]+w[x],-n-1,n+1),t2=ask(T[x],dep[x]-w[x],-n-1,n+1);ans[x]=t1+t2;if(!w[x])ans[x]-=t1;
}
inline void add_e(int u,int v);
signed main()
{
//    freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);int u,v;for(int i=1;i<n;i++){scanf("%d%d",&u,&v);add_e(u,v);du[v]++;}for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++)if(!du[i]){root=i;break;}dfs(root,1,0);for(int i=1;i<=20;i++)for(int j=1;j<=n;j++)f[j][i]=f[f[j][i-1]][i-1];int s,t;for(int i=1;i<=m;i++){scanf("%d%d",&s,&t);int lca=LCA(s,t);add(T[s],dep[s],1,-n-1,n+1);if(lca!=root){add(T[f[lca][0]],dep[s],-1,-n-1,n+1);}add(T[t],2*dep[lca]-dep[s],1,-n-1,n+1);add(T[lca],2*dep[lca]-dep[s],-1,-n-1,n+1);}dfs2(root);printf("%d",ans[1]);for(int i=2;i<=n;i++)printf(" %d",ans[i]);
}
inline void add_e(int u,int v)
{++num_e;u(num_e)=u;v(num_e)=v;n(num_e)=f(u);f(u)=num_e;
}

View Code

转载于:https://www.cnblogs.com/Al-Ca/p/11179295.html

NOIP2016天天爱跑步相关推荐

  1. [NOIp2016]天天爱跑步 线段树合并

    [NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...

  2. [NOIP2016]天天爱跑步(lca+乱搞)

    2557. [NOIP2016]天天爱跑步 时间限制:2 s   内存限制:512 MB [题目描述] 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑 ...

  3. $NOIP2016$天天爱跑步

    \(NOIP2016\)天天爱跑步 真\(™\)是\(NOIP\)近几年中最难的一道-- 先看一下部分分,有起点终点为根节点的分值,想到拆路径,对于路径\((S,T)\),拆为\((S,LCA)\)和 ...

  4. NOIP2016天天爱跑步 题解报告【lca+树上统计(桶)】

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

  5. [NOIP2016]天天爱跑步 题解(树上差分) (码长短跑的快)

    Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要 玩家每天按时上线,完成打卡任务.这个游戏的地图 ...

  6. [noip2016]天天爱跑步

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

  7. 【题解】NOIP-2016 天天爱跑步

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

  8. [noip2016]天天爱跑步(主席树+lca)

    恩..在百度的第一页翻了翻,没有用主席树做的,于是打算水一篇blog: 天天爱跑步 首先有一个解题的关键: 将玩家的向上和向下分成两部分: 先定义几个变量,s是起点,t是终点,wi是每个观察员出现的时 ...

  9. NOIP2016 天天爱跑步(线段树/桶)

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

最新文章

  1. linux基础命令_2
  2. Qt Style Sheet 翻译(中)--类似css
  3. Oracle使用dblink连接SqlServer
  4. matlab0-255的颜色映射到0-1,python中的matlab颜色映射
  5. nodejs里的module.exports和exports
  6. 数据按时间拆开分批处理示例
  7. Windows环境下smarty安装最简明教程 分享
  8. 对‘pthread_create’未定义的引用_2018年度‘龙虎榜’统计分析(一)
  9. 电容笔和触控笔哪个好?2022年电容笔推荐选购指南
  10. 路由器当交换机用,应该怎样配置?
  11. java pgm_如何读取Java中的PGM图像?
  12. 问题解决:Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist:...
  13. Agv、Rgv 车辆控制调度系统开发第一篇
  14. 人工智能技术的应用越来越广,极大促进了无人机产业的发展
  15. 免费的B站短链生成器,将链接转成b23.tv
  16. 转自科学网:《评论:“副教授,我缺少的是什么?”》
  17. 淘宝,天猫,京东,苏宁抢购茅台、手机等脚本(适合兼职,亲测可用)
  18. WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
  19. 在linux下设置php效劳器Apache2.2.3 mysql5.0.22 php5.2.0(2)
  20. 库克暗示观念差异阻碍苹果和Facebook合作

热门文章

  1. 2022-2028年中国微型汽车市场投资分析及前景预测报告
  2. SQL与NoSQL的区别 以MySQL与MongoDB为例
  3. centos7ftp服务器的搭建
  4. 【SpringMVC】概述
  5. 【C#】枚举_结构体_数组
  6. Python错误:AttributeError: 'generator' object has no attribute 'next'解决办法
  7. tensorflow op tf.global_variables_initializer
  8. LeetCode简单题之最少操作使数组递增
  9. LeetCode简单题之柠檬水找零
  10. TVM性能评估分析(四)