NOIP2016洛谷P1600:天天爱跑步

文章目录

  • 解析
    • sol1:树剖+map
    • sol2:树剖+离线
    • sol3:dfs维护树状数组+差分

解析

个人认为本题比同年的逛公园可做许多

本题的一个关键是:把慢跑者(u,v)(u,v)(u,v)转化为上升路径上满足depx+tx=depudep_x+t_x=dep_udepx+tx=depu的结点和下降路径上满足−dep+x+tx=depu−2∗deplca-dep+x+t_x=dep_u-2*dep_{lca}dep+x+tx=depu2deplca的结点x的答案均加一

这个感觉不是很难想,由于每秒跑一步的特性,很容易想到这个和深度的联系

然后就是怎么维护上面那个玩意了

sol1:树剖+map

时间复杂度:O(nlogn^3)
得分:95pts
这是我一开始想到的解法
第一交95pts也可以接受了吧
极其好写
就是对线段树每个结点开个map,做一个标记永久化,然后询问的时候沿途把标记捡起来就行了
修改过程中只会在最终打标记处改变map
一开始我觉得这个改变次数是O(1)的,但是这个是**假的!!**在最差情况下会退化成Ologn个(比如修改[1,n-1]的区间时)
这样复杂度就升到了nlogn^3,无法通过了
T掉3e5的数据也是合情合理
由于树剖自带的小常数+氧气加持+上面那个第三个log完全跑不满(现在终于可以默认有O2了!),得到95分也算合理
(然而关掉氧气由于垃圾的map常数就只有25pts)

sol2:树剖+离线

时间复杂度:nlogn^2
得分:100pts
稍微思考一下就可以想到真的做法
注意到所有的操作和询问都是针对一个特定的值,把他们离线下来从大到小处理即可
询问的时候用到一个先减后加从而求出变化量
这个就跑的飞快了
也不再耗氧
### 代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define debug(a,b) fprintf(stderr,a,b)
const int N=3e5+100;
const double eps=1e-9;
inline ll read() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
struct node {int to,nxt;
} p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y) {p[++cnt]=(node) {y,fi[x]};fi[x]=cnt;return;
}
int fa[N],siz[N],dep[N],hson[N],top[N],dfn[N],pos[N],tim;
void dfs1(int x,int f) {fa[x]=f;dep[x]=dep[f]+1;siz[x]=1;for(int i=fi[x]; ~i; i=p[i].nxt) {int to=p[i].to;if(to==f) continue;dfs1(to,x);siz[x]+=siz[to];if(siz[to]>siz[hson[x]]) hson[x]=to;}return;
}
void dfs2(int x,int tp) {top[x]=tp;dfn[++tim]=x;pos[x]=tim;if(hson[x]) dfs2(hson[x],tp);for(int i=fi[x]; ~i; i=p[i].nxt) {int to=p[i].to;if(to==hson[x]||to==fa[x]) continue;dfs2(to,to);}return;
}
inline int Lca(int x,int y){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=fa[top[x]];} if(dep[x]<dep[y]) swap(x,y);return y;
}#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)int ans[N];struct tree{int val[N<<2];int ask(int k,int l,int r,int x){int res=val[k];if(l==r) return res;if(x<=mid) return ask(ls,l,mid,x)+res;else return ask(rs,mid+1,r,x)+res;}void change(int k,int l,int r,int x,int y){if(x>y) return;//printf("k=%d (%d %d) x=%d y=%d v=%d\n",k,l,r,x,y,v);if(x<=l&&r<=y){val[k]++;return;}if(x<=mid) change(ls,l,mid,x,y);if(y>mid) change(rs,mid+1,r,x,y);return;}inline void Add(int x,int anc,int flag){while(top[x]!=top[anc]){change(1,1,n,pos[top[x]],pos[x]);x=fa[top[x]];}change(1,1,n,pos[anc]+flag,pos[x]);return;}
}t[2];int tt[N];int tot1,tot2;
struct ope{int x,anc,val,op;bool operator < (const ope u)const{return val<u.val;}
}o[N<<1];
struct query{int x,val,op;bool operator < (const query u)const{return val<u.val;}
}q[N<<1];
int main() {
#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1; i<n; i++) {int x=read(),y=read();addline(x,y);addline(y,x);}dfs1(1,0);dfs2(1,1);for(int i=1;i<=n;i++){tt[i]=read();q[++tot1]=(query){i,tt[i]+dep[i],0};q[++tot1]=(query){i,tt[i]-dep[i],1};}//for(int i=1;i<=n;i++) printf("x=%d fa=%d dep=%d t=%d pos=%d v1=%d v2=%d\n",i,fa[i],dep[i],t[i],pos[i],t[i]+dep[i],t[i]-dep[i]);for(int i=1;i<=m;i++){int x=read(),y=read();int lca=Lca(x,y);o[++tot2]=(ope){x,lca,dep[x],0};o[++tot2]=(ope){y,lca,dep[x]-2*dep[lca],1};//t1.Add(x,lca,dep[x],1);//t2.Add(y,lca,dep[x]-2*dep[lca],0);//printf("x=%d y=%d lca=%d v1=%d v2=%d\n",x,y,lca,dep[x],dep[x]-2*dep[lca]);}sort(q+1,q+1+tot1);sort(o+1,o+1+tot2);int pl1=1,pl2=1;for(int tim=-2*n;tim<=2*n;tim++){for(int i=pl1;i<=tot1&&q[i].val==tim;i++){int now=q[i].x;ans[now]-=t[q[i].op].ask(1,1,n,pos[now]);}while(pl2<=tot2&&o[pl2].val==tim){t[o[pl2].op].Add(o[pl2].x,o[pl2].anc,o[pl2].op);++pl2;}while(pl1<=tot1&&q[pl1].val==tim){int now=q[pl1].x;ans[now]+=t[q[pl1].op].ask(1,1,n,pos[now]);++pl1;}}for(int i=1;i<=n;i++){printf("%d ",ans[i]);}return 0;
}
/*
6 1
2 3
1 2 
1 4 
4 5 
4 6 
0 2 5 1 2 3
1 5
*/

sol3:dfs维护树状数组+差分

时间复杂度:nlogn
得分:100pts
写完看的题解的思路
这个东西是真的好强大
有点四两拨千斤的感觉
以后可以多往这方面想一想
就是把我上面维护的东西离线到各个结点上
维护树状数组并利用前后差值求出答案
(应该)跑的飞快
说是应该是因为我并没有再写一遍

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

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

相关文章

将 Visual Studio 的代码片段导出到 VS Code

导语和原文作者一样&#xff0c;水弟我现在也是使用 VS Code 和 Rider 作为主力开发工具&#xff0c;尤其是 VS Code 可以跨平台&#xff0c;又有丰富的插件支持和多种编程语言支持。当我从 VS 转移到以 VS Code 的开发过程中&#xff0c;遇到的最大问题就是代码提示的不完善&a…

2020 Jiangsu Collegiate Programming Contest

比赛链接 题号题目难易考点Gym 102875AArray难线段树&#xff0c;欧拉降幂Gym 102875BBuilding BlocksGym 102875CCats签到题贪心&#xff0c;思维Gym 102875DDelete Prime中模拟&#xff0c;暴力Gym 102875EEliminate the VirusGym 102875FFlee from MazeGym 102875GGrid Col…

P3835-[模板]可持久化平衡树【无旋Treap】

正题 题目链接:https://www.luogu.com.cn/problem/P3835 题目大意 一个空可重集&#xff0c;要求支持 插入一个数xxx删除一个数xxx询问一个数xxx的排名询问排名第xxx的数字询问xxx的前驱询问xxx的后继 但是所有操作都是基于某个历史版本 1≤n≤5105,1≤∣x∣≤1091\leq n\l…

洛谷P1450:硬币购物(背包、容斥)

解析 呜呜呜不废啊 我只会跑n遍多重背包 感觉非常神仙的一道题 之所以只是蓝的可能是因为代码实现难度太低了吧 但感觉思想真的很难想到 也可能是我太菜了 容斥相关还是需要加强啊qwq 考虑如果没有硬币个数的限制的情况 显然就是个简单的完全背包了 然而如今有了硬币个数的限…

Maze (FFT+快速幂)

Description 众维拉先后在中土大陆上创造了精灵、人类以及矮人&#xff0c;其中矮人是生性喜好常年居住在地下的洞穴的存在&#xff0c;他们挖掘矿物甚至宝石&#xff0c;甚至用他们的勤劳勇敢智慧在地底下创造出了辉煌宏大的宫殿&#xff0c;错综复杂的迷宫——嗯&#xff0c…

如何基于 Kubernetes 构建完整的 DevOps 流水线

前言关于 DevOps 是一个很大的话题&#xff0c;它可能既涉及到公司的技术文化构建&#xff0c;也包括开发者技术能力的支持&#xff0c;这次技术干货分享主要是侧重于技术方面&#xff0c;就是如何用 Kubernetes 来服务好 DevOps 的流水线。本文从 4 个方面介绍&#xff1a;什么…

C - Cats Gym - 102875C

C - Cats Gym - 102875C 题意&#xff1a; n个猫&#xff0c;猫的身高在1到20之间&#xff0c;现在求这些猫的排列&#xff0c;满足一样高的猫不靠着&#xff0c;且他们之间的最矮的猫不比他们高 输出任意符合条件的排列 题解&#xff1a; 构造题 题目的限制条件决定了&…

CF702F-T-Shirts【FhqTreap】

正题 题目链接:https://www.luogu.com.cn/problem/CF702F 题目大意 有nnn个物品&#xff0c;第iii个价格为cic_ici​&#xff0c;质量为qiq_iqi​。 然后有mmm个询问&#xff0c;假设一个人有viv_ivi​块&#xff0c;他每次会买他能买得起的qiq_iqi​最大的&#xff08;如果…

P3160:局部极小值(容斥、状压)

解析 又是一道我不会的容斥题 qwq 本题的一个关键性质:答案有解时&#xff0c;极小值不超过8个 所以可以对其进行状压 考虑从小到大填数 那么在极小值填完之前&#xff0c;它的八连通必然是不能填的 设计dpi,sdp_{i,s}dpi,s​表示从小到大填了i个数&#xff0c;已经填完的极…

[SNOI2017]遗失的答案 (FWT)

description 小皮球在计算出答案之后&#xff0c;买了一堆皮肤&#xff0c;他心里很开心&#xff0c;但是一不小心&#xff0c;就忘记自己买了哪些皮肤了。 ||| 万幸的是&#xff0c;他还记得他把所有皮肤按照 1∼N 来编号&#xff0c;他买来的那些皮肤的编号&#xff08;他至…

Abp中使用可视化的日志面板

如果你还不了解LogDashboard请看这里 使用logdashboard查看可视化日志。ABP的相关知识不做介绍如果有需要请阅读ABP官方文档ABP是Net下非常优秀的开发框架,在中国很多的项目都正在使用它。现在我们可以使用LogDashboard增强在使用ABP开发中的查看日志能力。下载ABP模板项目打开…

J - Just Multiplicative Inverse Gym - 102875J

J - Just Multiplicative Inverse Gym - 102875J 题目&#xff1a; 题解&#xff1a; 给定一个x&#xff0c;求出F(1,x)F(2,x)…F(x-1,x) 的和除以&#xff08;x-1&#xff09; F(x,p)题目已经给出 我们观察F()含义&#xff0c;再结合本题含义&#xff0c;本题并不是要求F(x,…

P7137-[THUPC2021 初赛]切切糕【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P7137 题目大意 有两个人&#xff0c;有nnn个蛋糕&#xff0c;第iii个蛋糕大小为aia_iai​。 每一次第一个人可以选择一个蛋糕把它切成任意大小的两份&#xff08;一份可以为空&#xff09;。 然后第二个人有mmm次机会优先…

利用Topshelf把.NET Core Generic Host管理的应用程序部署为Windows服务

2019第一篇文章。此文源于前公司在迁移项目到.NET Core的过程中&#xff0c;希望使用Generic Host来管理定时任务程序时&#xff0c;没法部署到Windows服务的问题&#xff0c;而且官方也没给出解决方案&#xff0c;只能关注一下官方issue #809 等他们方解决了。官方文档只提供了…

洛谷P3270:成绩比较(容斥、组合数学)

解析 依然不会亚qwq 但这次至少有点上道了 (指推出了一个会导致重复计数的错误式子) 首先&#xff0c;我们要选出碾压那些人&#xff0c;方案数就是Cn−1kC_{n-1}^kCn−1k​ 然后&#xff0c;我们要统计每门学科的排名情况 考虑比B神分数高的人一定是从没被碾压的人里选。所…

游戏 (匈牙利)

description 在 2016 年&#xff0c;佳媛姐姐喜欢上了一款游戏&#xff0c;叫做泡泡堂。 简单的说&#xff0c;这个游戏就是在一张地图上放上若干个炸弹&#xff0c;看是否能炸到对手&#xff0c;或者躲开对手的炸弹。在玩游戏的过程中&#xff0c;小 H 想到了这样一个问题&a…

D - Delete Prime Gym - 102875D

D - Delete Prime Gym - 102875D 题意&#xff1a; 长度为n的序列&#xff0c;每次从中取出编号为1或质数的数&#xff0c;组成新的序列d 现在给一个k&#xff0c;问序列中哪一位的值是k以及序列中第k位是多少 共T个询问 T< 2 * 105 n&#xff0c;k< 105 题解&#…

CF1628A-Meximum Array【二分】

正题 题目链接:http://codeforces.com/contest/1628/problem/A 题目大意 给出一个长度为nnn的序列aaa和一个空序列bbb&#xff0c;你每次可以选择aaa的一个前缀&#xff0c;将它的mexmexmex加入序列bbb的末尾&#xff0c;然后将aaa的这个前缀删除。 求bbb的最大字典序。 1≤…

gym 102875 H. Happy Morse Code

gym 102875 H. Happy Morse Code 题意&#xff1a; 一个长度为n的字符串&#xff0c;现在给你m个小字符串&#xff0c;问小字符串拼成大字符串有多少种方法&#xff1f; 答案mod128 题解&#xff1a; 其实也不难&#xff0c;但是本人对于dp及其不敏感&#xff0c;我看出来是…

开源项目商业模式分析(2) - 持续维护的重要性 - Selenium和WatiN

该系列第一篇发布后收到不少反馈&#xff0c;包括&#xff1a;第一篇里说的MonicaHQ不一定盈利没错&#xff0c;但是问题在于绝大多数开源项目商业数据并没有公开&#xff0c;从而无法判断其具体是否盈利。难得MonicaHQ是公开的&#xff0c;所以才用来做这系列文章的开篇。很多…