显然的是,没有被赋过值的点,赋上a能保证字典序最小
不论何种方法,最终的目的是不要让一个位置被重复赋值
这题最重要的注意点是,区间可以从1e6开始,长度是1e6,所以字符串数组ans要开到2e6
另一个注意点是,对于要将所有字符串存下来做统一处理的做法,因为不确定每个字符串的长度,开的太大会mle,所以逼不得已要用string,裸的cin读入会超时
别忘了加ios::sync_with_stdio(false)
很容易想到的一个方法是将所有区间扔进数组按左端点排序
记录一个当前处理到的位置cur
如果当前区间左端点小于cur,就从cur更新到右端点(有可能cur也大于右端点,那就不更新跳过该区间)
如果左端点大于cur就老老实实更新
这样是O(2000000logn)的
#include
#include
#include
#include
#include
#include
#include
#include
#include
另一个很容易想到的做法是用线段树
维护区间是否已经赋过值
不过这样有点overkill
#include
#include
#include
#include
#include
#include
#include
#include
#include
一个比较标准的解法是用set
开一个set来维护还没有赋值过的位置
每次读入一个l,r以后,用lower_bound来查找区间内没有被赋值的点,赋值以后从set里扔出去
#include
#include
#include
#include
#include
#include
#include
#include
#include
相似的思路,用dsu来维护可以大幅提升效率
一个点如果已经赋过值,就合并i和i+1
这种做法很像356B Knight Tournament
#include
#include
#include
#include
#include
#include
#include
#include
#include
有一种十分有趣的做法
对于每个区间i,在开始处打标记i,在结束处打标记-i
把每个位置扫一遍
开一个set表示包含了当前位置的那些区间
扫到位置i时,查看所有的标记,如果是正的,将该区间扔进set,如果是负的,将该区间扔出set
如果set是空的,赋上a
#include
#include
#include
#include
#include
#include
#include
#include
#include