2018 杭电多校1 - Distinct Values
Chiaki has an array of n positive integers. You are told some facts about the array: for every two elements $$$a_i$$$ and $$$a_j$$$ in the subarray $$$a_{l,r} (l ≤ i < j ≤ r )$$$, $$$a_i≠a_j$$$ holds.
Chiaki would like to find a lexicographically minimal array which meets the facts.
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n,m (1 ≤ n,m ≤ 10$$$^5$$$) -- the length of the array and the number of facts. Each of the next m lines contains two integers $$$ l_i$$$ and $$$r_i$$$ (1 ≤ $$$l_i$$$ ≤ $$$r_i$$$ ≤ 10$$$^5$$$)
It is guaranteed that neither the sum of all n nor the sum for all m exceeds 10$$$^6$$$.
For each test case, output n integers denoting the lexicographically minimal array. Integers should be separated by a single space, and no extra spaces are allowed at the end of lines.
3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4
1 2
1 2 1 2
1 2 3 1 1
【题意】
给m个区间[$$$l_i, r_i$$$],要构造一个长度为n的串,每个区间内的数不能有相同的,且整个串的字典序最小
【思路】
要求字典序最小,自然想到要按从左到右的顺序对串进行填充,因为最左边的区间一定是从1开始填的,而它一旦填充,由于区间重叠,就会对后面的区间造成影响。在填充的过程中有两个问题需要解决:如何寻找下一个区间?如何维护下一个区间可以使用的数字?
首先可以肯定的是,如果一个区间被更大的区间包含,就再也不需要考虑它了,因为大的区间满足它也一定满足;因此,需要考虑的区间只可能两两重叠,或不重叠,所以它们的左右端点与其他区间都不一样。
假设现在处理到了位置$$$i$$$,有一个集合M,记录的是当前可用的所有数字,为了更快的生成M,不能每次都把所有数遍历一遍。从M中去掉位置$$$i$$$选择的数后,继续填充下一个位置$$$i+1$$$有两种可能:两点在同一个区间内,这样$$$i+1$$$直接从M中选一个最小的;两点在不同区间,这个时候[$$$l_{i+1},r_{i+1}$$$]可能已经填充了一部分了,也就是两区间的重叠部分[$$$l_{i+1},r_i$$$],M要加入一些数,变为[$$$l_i,l_{i+1}-1$$$]$$$\cup$$$ M,再取出最小的数填充到$$$i+1$$$。
因此,在填数的过程中需要不断获取区间的起点,对每个位置,都需要知道一个它所在的左端点。同一个位置可能会被多个区间覆盖,但由于实际填数的时候从左到右,所以只需要考虑最靠左的左端点。如果用预处理一遍用数组pre[]记录所有位置的这样的左端点,这些值的意义就是在处理位置$$$i$$$时,必须和位置pre[i]~$$$i-1$$$的数都不相同。
有了预处理以后,当前可用的数字集合M的维护过程就是,$$$M_{(i+1)} = (M_{(i)}-{ans[i]})\cup\{ans[t]|t\in[pre[i], i-1]\}$$$。M上的操作:插入删除,求最小,所以可以用set来实现。
【代码】
#include<stdio.h>
#include<set>
using std::set;
using std::pair;
#define N_max 100005
typedef pair<int,int> PII;
typedef long long LL;
#define INF 0x3f3f3f3f
PII ipt[N_max];
int ans[N_max];int n, m;
int pre[N_max];
int main() {
int kase;
scanf("%d", &kase);
while (kase--)
{
scanf("%d %d", &n, &m);
int del = ; //所有右端点初始化为指向本身
for (int i = ; i <= n; i++)
{
pre[i] = i;
ans[i] = ;
} //输入并只记录最小的左端点
for (int i = ; i<m; ++i)
{
scanf("%d %d", &ipt[i].first, &ipt[i].second);
if (pre[ipt[i].second] > ipt[i].first)
pre[ipt[i].second] = ipt[i].first;
}
//更远的pre[i+1]会把pre[i]扩大到同样远
for (int i = n - ; i >= ; --i)
{
if (pre[i] >= pre[i + ])pre[i] = pre[i + ];
}
set<int>help;//最开始的时候把所有数都放进去
for (int i = ; i <= n + ; ++i)help.insert(i); for (int ri = ; ri <= n; ri++)//给所有位置选一个数
{
for (int t = pre[ri - ]; t<pre[ri]; ++t)//补充help
{
help.insert(ans[t]);
}
ans[ri] = *help.begin();//set的第一个数就是最小的
help.erase(help.begin());
}
for (int i = ; i <= n; ++i)printf("%d%c", ans[i], i == n ? '\n' : ' ');
} return ;
}
【总结】
看了很久标程,结合自己的理解写出来了。反思了一下之前自己的写法差不多,但是超时的原因,很有可能是在可用集合的维护上不够精简。如果每次直接填好一个区间→更新M→填下一个区间,其实很多数字在真正被使用前就已经被反复插入/删除了很多次,很浪费时间。
2018 杭电多校1 - Distinct Values的更多相关文章
- hdu6312 2018杭电多校第二场 1004 D Game 博弈
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 【2020杭电多校】Distinct Sub-palindromes 找规律
题目链接:Distinct Sub-palindromes 题意: 给你一个长度n,你需要找出来一些串,这些串由A...Z和a...z构成.我们设长度为n的所有串中所包含回文子串最少的数量为ans.问 ...
- 2018 杭电多校3 - M.Walking Plan
题目链接 Problem Description There are $$$n$$$ intersections in Bytetown, connected with $$$m$$$ one way ...
- 2018 杭电多校1 - Chiaki Sequence Revisited
题目链接 Problem Description Chiaki is interested in an infinite sequence $$$a_1,a_2,a_3,...,$$$ which i ...
- 2018 杭电多校2 - Naive Operations
题目链接 Problem Description In a galaxy far, far away, there are two integer sequence a and b of length ...
- 2018杭电多校第二场1003(DFS,欧拉回路)
#include<bits/stdc++.h>using namespace std;int n,m;int x,y;int num,cnt;int degree[100007],vis[ ...
- 2018杭电多校第六场1009(DFS,思维)
#include<bits/stdc++.h>using namespace std;int a[100010];char s[20];int zhiren[100010];vector& ...
- 2018杭电多校第五场1002(暴力DFS【数位】,剪枝)
//never use translation#include<bits/stdc++.h>using namespace std;int k;char a[20];//储存每个数的数值i ...
- 2018杭电多校第三场1003(状态压缩DP)
#include<bits/stdc++.h>using namespace std;const int mod =1e9+7;int dp[1<<10];int cnt[1& ...
随机推荐
- 北京Uber优步司机奖励政策(3月28日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- restTemplate访问接口
后端技术精选 每天推送精选技术好文,涉及Java.python.Linux及MySQL,欢迎关注微信公众号:后端技术精选 随笔 - 52, 文章 - 0, 评论 - 50, 引用 - 0 Spring ...
- 华天正real210开发板测试-第1篇
1. 网上买的real210二手开发板,今天刚到测试一下 2. 启动方式,不过目前唯一的问题是没有开发资料,然后给原厂发了份邮件要资料,原厂爽快的给了,必须给华天正这服务态度点个赞啊 3. 调到nan ...
- nodeJs 安装 npm nodeModules package.json
Nodejs 1.安装nodejs 从nodejs官网下载最新版本的node,设置环境变量这样就可以在cmd下直接用命令行操作npm 环境变量:path d:/nodejs 查看本机node及n ...
- 「Python」matplotlib备忘录
总结了一下网上现有的资源,得到了一些东西.随手做个备忘. 更多设置见:https://matplotlib.org/users/customizing.html. 导入 import matplotl ...
- 汽车VIN码识别/汽车车架号OCR识别,移动端VIN码识别,OCR扫描工具
本文推荐了一项汽车VIN码自动识别技术,用户通过手机“扫一扫”的简单操作,就可以快速识别VIN码,查询到车辆的详细信息,为汽修汽配.二手车交易.车辆监管.查勘理赔提高工作效率. VIN是英文Vehic ...
- 怎样安装Android Studio
在浏览器地址栏输入 http://www.android-studio.org/ 打开Android Studio中文社区, 下载安装包: 这里需要注意的是SDK的目录, 我没有选择默认的目录, 而是 ...
- Shader Forge学习
最近学习了一下shader forge,一个屌屌哒插件用来生成shader.尽管其降低了制作shader的难度,但是真的想做出满意的shader的话还是得有一定的shader基础.但是仅仅是做出一些简 ...
- 孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境
孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境 (完整学习过程屏幕记录视频地址在文末) 学习Python我肯定不会错过图片文字的识别,当然更重要的是简单的验证码识别了,今天 ...
- 给eclipse安装color-theme插件
给eclipse安装color-theme插件 2016年03月22日 19:16:01 ming_love 阅读数:5193 标签: Eclipse Color Theme 更多 个人分类: jav ...