IOI2014例题
这个东西还是应该写写博客的,毕竟IOI
题目连接已给出,直接点击大标题(推荐网络OJ:Universal Online Judge)
IOI2014 Rail
题目有点难看,耐心……
题目是说给出任意两段车站的距离(你只能得知其中的
距离的定义请看题
题目保证
直接说正确的解法(部分分很水请独立思考)
我们会发现:
1.车站
2.离距离某个
根据以上两条,我们可以按照如下步骤操作:
1.求出所有其它车站到
由此我们可以根据距离关系将剩下的车站分为两类:
1.位于
2.位于
仔细观察发现,此时
就此我们又可以将
1.位于
2.位于
现在问题剩下:
以
思考:
1.将右边所有车站按照到
对于剩下来的车站,我们维护一个
我们每次询问
我们可以通过计算得到
设
计算位置
如果合法且存在
否则,则说明位置
判断位置是否存在
上面这是干嘛呢?
其实仔细画个图看看就能明白
拿出笔和纸吧(^o^)/~
位置:
车站:
编号:
自己用笔和纸玩一玩就明白
这样我们就在限制条件
时间复杂度:O(n)或O(n log n)
IOI2014 Wall
维护一个长度为
线段树标记大法好!
什么?你不会线段树标记?
好吧,我们简单讲讲
如果我们每次区间修改都改到每个点上,显然是会超时的对不对?
为什么?
因为这样的话线段树就太勤快了
然而事实上它是很懒的……(扯淡而已︿( ̄︶ ̄)︿)
如果一个节点表示的区间都存在一个操作,我们可以先把这个操作放在这
也就是lazy标记
等到下次访问这个点的时候,我们再把标记下传
这样每次修改的复杂度就少了许多
但是为什么就不会TLE呢?(其实我也不知道╮(╯_╰)╭)
(网络上都说:IOI数据结构题对中国选手都是送分题……)
IOI2014 Game
这个题……
两个熊孩子玩游戏……
一个很容易理解的做法
对于每个询问
如果
否则就回答这条边不存在
为什么这样做呢?
如果我们在
如果这条边的询问放在后面,那么熊孩子健佳就输了……
实现可以使用邻接矩阵,并查集来实现
一个比较容易写的做法
妈妈你看,为什么它们的AC代码都这么短?
#include"game.h"
int a[1510];
void initialize(int){}
int hasEdge(int u,int v) { if (u<v) u=v; return ++a[u]==u; }
这只是碰巧么?
当然不是
考虑一下特殊的连通结构:树
我们控制:对于点
这样的话就严格控制了整个图为一棵树