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

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

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

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 yxy拆成上行段和下行段。

  • 若点iiix→yx\to yxy的上行段上,
    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]

  • 若点iiix→yx\to yxy的下行段上,
    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 yxy,我们将其拆成 上行段p:x→lca(x,y)p:x\to lca(x,y)p:xlca(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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core中的CSV解析库

感谢本篇首先特别感谢从此启程兄的《.NetCore外国一些高质量博客分享》, 发现很多国外的.NET Core技术博客资源, 我会不定期从中选择一些有意思的文章翻译总结一下。.NET Core中的CSV解析库本篇博客来源于.NET Core Totorials的《CSV Parsing In .NET Core》。背景介绍对于初级…

【manacher】双倍回文(金牌导航 manacher-2/luogu 4287)

双倍回文 金牌导航 manacher-2 luogu 4287 题目大意 设串为x&#xff0c;将其取反为x’&#xff0c;定义双倍回文为形如xx’xx’的串 现在给你一个字符串&#xff0c;让你求最大双倍回文子串 输入样例 16 ggabaabaabaaball输出样例 12数据范围 N⩽105N\leqslant 10^5N⩽…

P6178-[模板]Matrix-Tree 定理

正题 题目链接:https://www.luogu.com.cn/problem/P6178 题目大意 给出一个nnn个点mmm条边的无向/有向图。 求所有的生成树/以1为根的外向生成树的权值乘积和。 解题思路 矩阵AAA的行列式表示为det(A)det(A)det(A)&#xff0c;定义为 det(A)∑P(−1)μ(P)∏i1nAi,pidet(A)\…

可达性

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 给出一个 0 ≤ N ≤ 105 点数、0 ≤ M ≤ 105 边…

[集训队作业2018]小Z的礼物(min-max容斥,插头dp)

传送门 这种求 “取到所有物品的期望时间” 的题一般都用 min−maxmin-maxmin−max容斥 解决&#xff1a; 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j)(i,j)的期望时间&#xff0c;集合S∪c(i,j)′∗′{t(i,j)}S\cup_{c(i,j)*}\{t(i,j)\}S∪c(i,j)′∗′​{t(i,j)} 那么根据min−…

为什么要使用Entity Framework

本文介绍从DDD(Domain-Driven Design[领域驱动设计])的角度来说说为什么要使用Entity Framework(以下都会简称为EF)&#xff0c;同时也看出类似Drapper之类的简陋ORM不足的地方。设想业务都是大家知晓的权限管理&#xff0c;实体类如下。读到这里&#xff0c;请先思考一下&…

【Splay】波动值之和(金牌导航 Splay-1)

波动值之和 金牌导航 Splay-1 题目大意 给出一个数列&#xff0c;求∑i1nminj1i−1∣ai−aj∣\sum_{i1}^{n}min_{j1}^{i-1}|a_i-a_j|∑i1n​minj1i−1​∣ai​−aj​∣ 输入样例 6 5 1 2 5 4 6输出样例 12样例解释 5∣1−5∣∣2−1∣∣5−5∣∣4−5∣∣6−5∣541011125|1…

P4336-[SHOI2016]黑暗前的幻想乡【矩阵树定理,容斥】

正题 题目链接:https://www.luogu.com.cn/problem/P4336 题目大意 nnn个点&#xff0c;n−1n-1n−1个边集&#xff0c;求有多少种方案使得每个边集中恰好选出一条边使得这nnn个点连成一棵树。 解题思路 我们需要利用好n−1n-1n−1个边集这个性质&#xff0c;因为nnn很小&…

Tarjan算法

Tarjan算法可以应用在求解 强连通分量&#xff0c;缩点&#xff0c;桥&#xff0c;割点&#xff0c;双连通分量&#xff0c;LCA等 关于文章目录强连通分量代码题目tarjan求割点割点概念流程代码&#xff1a;求无向图的割边&#xff0f;桥理解&#xff1a;代码&#xff1a;强连通…

[集训队作业2018] 万圣节的积木(李超线段树)

传送门 设最底层为第1层&#xff0c;倒数第二层为第2层&#xff0c;以此类推。 发现若第111 ~ iii层构成的积木稳定&#xff0c;第111 ~ jjj (j>ij>ij>i)构成的积木也稳定&#xff0c; 那么第i1i1i1 ~ jjj层构成的积木一定也是稳定的。 所以我们只要找到所有的iii满…

Ocelot简易教程(一)之Ocelot是什么

简单的说Ocelot是一个用.NET Core实现并且开源的API网关技术。可能你又要问了&#xff0c;什么是API网关技术呢&#xff1f;Ocelot又有什么特别呢&#xff1f;我们又该如何集成到我们的asp.net core程序中呢&#xff1f;下面我会通过一些列通俗易懂的教程来为大家讲解。今天的这…

P5516-[MtOI2019]小铃的烦恼【期望dp,线性消元】

正题 题目链接:https://www.luogu.com.cn/problem/P5516 题目大意 nnn个字母的一个字符串&#xff0c;每次随机选取两个不同的位置(x,y)(x,y)(x,y)让第xxx个位置的字符变成第yyy个位置的字符。 求期望多少次能够把所有字符变成同一个。 解题思路 因为最终状态很多&#xff0…

如何在你的项目中集成 CAP【手把手视频教程】

前言之前录制过一期关于CAP的视频&#xff0c;但是由于当时是直播时录制的视频&#xff0c;背景音比较杂所以质量有点差。这次的视频没有直播&#xff0c;直接录制的&#xff0c;视频质量会好很多&#xff0c;第一遍录制完成之后发现播放到一半没有声音&#xff0c;所以又重新录…

【Splay】文艺平衡树(金牌导航 Splay-2)

#文艺平衡树 金牌导航 Splay-2 题目大意 给你一个1~n的序列&#xff0c;然后对序列的区间做若干次翻转&#xff0c;问你最后的序列 输入样例 5 3 1 3 1 3 1 4输出样例 4 3 2 1 5数据范围 1⩽n,m⩽105,1⩽l⩽r⩽n1\leqslant n,m\leqslant 10^5,1\leqslant l\leqslant r \l…

[集训队作业2018] 三角形(贪心,堆,线段树合并)

传送门 首先&#xff0c;在结点uuu放上w[u]w[u]w[u]个石子后&#xff0c;出于贪心考虑&#xff0c;下一步一定会把uuu的所有儿子vvv上的石子收回手中。 转换题意&#xff1a; 记cntcntcnt为当下树上的石子数&#xff0c;对每个结点uuu可以执行一次操作&#xff1a; step1. c…

P3527-[POI2011]MET-Meteors【整体二分,树状数组】

正题 题目链接:https://www.luogu.com.cn/problem/P3527 题目大意 mmm个格子形成的环&#xff0c;有nnn个集合&#xff0c;第iii个格子属于第oio_ioi​个集合&#xff0c;kkk次让环上一段的格子加上一个权值。 对于每个iii求出第iii个集合在多少次的时候它集合中的所有格子权…

.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现

前言本篇会继续讲解Sikiro.SMS.Job服务的实现&#xff0c;在我写第一篇的时候&#xff0c;我就发现我当时设计的架构里Sikiro.SMS.Job这个可以选择不需要&#xff0c;而使用MQ代替。但是为了说明调度任务使用实现也坚持写了下。后面会一篇针对架构、实现优化的讲解。源码地址&a…

Drainage Ditches POJ1273

Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 93263 Accepted: 36174试题链接 文章目录Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Dinic做法EK做法Description Every time it rains on Farmer John’s fields, a pond forms over Bessie’…

【主席树】可持久化数组(金牌导航 可持久化数据结构-3)

可持久化数组 金牌导航 可持久化数据结构-3 题目大意 给出一个序列a&#xff0c;让你执行若干操作&#xff0c;操作分为两种&#xff1a; 1.继承第v次操作后把第x个数改成y 2.查询第v次操作的第x个数的值 输入样例 5 10 59 46 14 87 41 0 2 1 0 1 1 14 0 1 1 57 0 1 1 88 …

[集训队作业2018] 复读机(生成函数,单位根反演)

传送门 subtask 1&#xff1a;d1d1d1 答案为knk^nkn。 subtask 2&#xff1a;n≤1000,k≤100n\leq1000,k\leq 100n≤1000,k≤100 设f[i][j]f[i][j]f[i][j]表示由iii个复读机来分jjj个时间点的方案数。 可以得到递推式&#xff1a; f[i][j]∑p0j[d∣p]Cjpf[i−1][j−p]f[i][j…