标签:ioi
这个东西还是应该写写博客的,毕竟IOI
题目连接已给出,直接点击大标题(推荐网络OJ:Universal Online Judge)
题目有点难看,耐心……
题目是说给出任意两段车站的距离(你只能得知其中的
距离的定义请看题
题目保证
直接说正确的解法(部分分很水请独立思考)
我们会发现:
1.车站
2.离距离某个
根据以上两条,我们可以按照如下步骤操作:
1.求出所有其它车站到
由此我们可以根据距离关系将剩下的车站分为两类:
1.位于
2.位于
仔细观察发现,此时
就此我们又可以将
1.位于
2.位于
现在问题剩下:
以
思考:
1.将右边所有车站按照到
对于剩下来的车站,我们维护一个
我们每次询问
我们可以通过计算得到
设
计算位置
如果合法且存在
否则,则说明位置
判断位置是否存在
上面这是干嘛呢?
其实仔细画个图看看就能明白
拿出笔和纸吧(^o^)/~
位置:
车站:
编号:
自己用笔和纸玩一玩就明白
这样我们就在限制条件
时间复杂度:
(
所以不会写的话可以去Orz一下)
题意很简单:
维护一个区间,支持两种操作:
1、将一段<=k的数全部变成k
2、将一段>=k的数全部变成k
线段树大法好啊!
神马你说你不会线段树打标记∑q|?Д?|p?
简单介绍一下:
意识流一下
把当前对于一个线段区间的操作暂时记录在这,即lazy
待到下一次访问该节点时,将标记操作实施,即向左右子节点下传
(如果不能明白,那就去自行百度下,像”算法竞赛入门经典训练指南”这类良心书上也有讲解)
对于这个题,维护一下标记和最大值、最小值即可
时间复杂度:
题意:给定询问点对的顺序,要求构造一张图,使得在所有询问执行完之前,对方无法判断整张图的连通性
两熊孩子玩游戏……
我们考虑一下每个询问
若
否则回答不存在
若存在另一条边
连通块的维护可以使用并查集维护
唯一要注意的是并查集合并时询问次数的合并
时间复杂度:近似
我的天哪!为什么我的快代码1K,人家代码100+B?
#include"game.h"
int a[1510];
void initialize(int) {}
int hasEdge(int u,int v)
{
if (u<v) u=v;
return ++a[u]==u;
}
(恶意缩行其实是不好的行为,小伙伴们不要学习啊╭(╯^╰)╮!)
这这这!这是怎么过的啊(大雾)?
嗯(⊙v⊙),我们来考虑一个这样的东西:树
我们尝试维护:每个点相对与编号比它小的点只有一条边
这样的话,整个图最后一定是一棵树
在最后一条边被询问之前,整个图的连通性是不确定的
时间复杂度:
(梅玉:健佳你太赖皮了,再也不和你玩了!)
(健佳:……)
题意太长自己看……
我们考虑一下原来的序列
这个序列可以循环变动
新的缆车可以在任意时刻换下任意一辆缆车
所以我们只需考虑一下最开始的缆车
嗯对就是这样
那如果最开始的缆车
输出
(
(
时间复杂度:
根据上面的推论,我们模拟一下每辆缆车换上来的顺序:
若当前缆车存在于
否则放在任意一个位置上,满足当前情况下该位置
为了方便起见,我们将这个任意位置定为
时间复杂度:
MOD=1000000009
这个比上面两个有技术含量多了
增加了一种基于分治思想的快速计算方法(不是
(O(∩_∩)O哈哈~我就不行你能把我的头压在键盘上fahsdglebangekjbalgbdska……)
MOD=1000000009
妈呀!
我们将
诶,我们会发现有些缆车先换上来又换下去了,而且答案主要就是他们玩大的!
等等!
在相邻的
快速幂搞搞就A了!
MOD=1000000009
(
MOD=1000000009,我都写了四遍了你还不取模自己看着办
时间复杂度:
题目意思自己看……
啥?我没看错吧?一般图最大权独立点集不是NP-hard问题么(NP难题请自行百度)?
众所周知,NP-hard问题是没有精确算法的(说不定以后有哪位Orz搞出来了)
(
如果你去想最大权独立点集问题,恭喜你掉坑里了!
我们不妨换一个思想:考虑
这样我们就构成了一颗树
再把不同的连边方式作为不同的边权放在边上
嗯,这应该是树形DP
恭喜你猜中正解!
我们定义:
yes[i]——在以i为根的子树可以选择点i时的最大点权独立集
no[i]——在以i为根的子树不可以选择点i时的最大点权独立集
(
1.若
2.若
3.若
如果我们之前决策选择过一个编号较小的
嗯,一个
妈妈你看!人家的AC代码怎么又比我短一截啊?
#include "friend.h"
#define max(a,b) ((a)>(b)?(a):(b))
int G[100005];
int findSample(int N,int F[],int H[],int O[])
{
for (int i=N-1;i;i--)
{
int x=H[i];
if (O[i]==0)
F[x]+=G[i],G[x]+=max(F[i],G[i]);
if (O[i]==1)
F[x]=max(F[x]+max(F[i],G[i]),G[x]+F[i]),G[x]+=G[i];
if (O[i]==2)
F[x]=max(F[x]+G[i],G[x]+F[i]),G[x]+=G[i];
}
return max(F[0],G[0]);
}
(只能说博主自带代码复杂度翻倍的BUFF,具体多少倍看题吧……)
大神:“嗯,很显然,这两个
博主:“我还是太弱了……”
题目意思一样自己看nglajksdgnawn……
嗯,第一眼看完:不会o(>﹏<)o……
不过我们会发现,子任务2的起点是固定在最左的
嗯,对于子任务2,一定是一次性从左走到右,然后在路途中玩上几天
枚举走的天数+函数式线段树求区间前k大值之和水过?
啥?函数式线段树是啥?
不会的自行百度吧……(你也可以使用主席树,没什么差别)
简单扯一两句:
假设我们要维护一颗线段树,它支持
我们可以通过新建节点来代替原先的修改操作,从而实现全信息保存
嗯,由于线段树单点修改每次只会影响一条链的值,改一条链即可
空间复杂度:
时间复杂度:
思考:对于其他任务,我们每次一定只存在四种情况:
1、一直向右,路上玩
2、先向右再向左,路上玩
3、先向左再向右,路上玩
4、一直向左,路上玩
我们回过头来看看子任务2
设
显然
我们会发现:
意识流:当天数增加一天时,我们可以选择在之前的城市中再多玩一天,或者多走一天到达下一个城市
意识流告诉我们,可以数学归纳证明,这里不再赘述
同理,另外三个函数值(向左边行动,向右边行动后折返回出发点,向左边行动后折返回)同样具有单调性
嗯,不错的想法
决策的单调性有什么用呢?
问题转化一下:
函数
我们定义
我们先枚举
(处理值的方法:上面提到过)
利用决策的单调性,递归处理定义域为
因为决策单调性,两者的值域变为
通过计算时间复杂度可知为
我们处理出四个函数的值,再进行各阶段天数的枚举
OK,最后一题就这样A了!
等等,我怎么MLE了?
请注意空间限制:
如果TLE了的话请注意一下你的线段树(少维护一些左右区间范围啊这种没用的东西)
时间复杂度:
嗯,IOI2014完结撒花!
标签:ioi
原文地址:http://blog.csdn.net/tgop_knight/article/details/44727595