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& ...
随机推荐
- 破解有道词典在线翻译接口--python
没什么好说的,直接上代码. import requests # import json import time import random import hashlib translate = inp ...
- 博科Brocade 300光纤交换机配置zone教程
光纤交换机作为SAN网络的重要组成部分,在日常应用中非常普遍,本次将以常用的博科交换机介绍基本的配置方法. 博科300实物图: 环境描述: 如上图,四台服务器通过各自的双HBA卡连接至两台博科300光 ...
- Windows下的SysWow64和System32
64位的Windows并不是简单地把所有东西都编译成64位就万事大吉的.关于64位的CPU应该做成什么样子,Intel和AMD曾有各自的打算.AMD的回答直接了当:新的64位处理器,应该能在提高更高处 ...
- DevExpress TreeList用法总结
http://blog.itpub.net/29251214/viewspace-774395/ http://blog.csdn.net/czp_huster/article/details/501 ...
- logback.xml日志文件配置
放在resources目录下面就可以自动读取<?xml version="1.0" encoding="UTF-8"?> <configura ...
- swoole 相关
安装虚拟机 VMware Workstation Pro 安装CentOS CentOS-7-x86_64-Minimal-1708.iso 安装FinalShell 教程地址 安装lnmp 教程地址 ...
- Andorid自定义attr的各种坑
本文来自网易云社区 作者:孙有军 在开发Andorid应用程序中,经常会自定义View来实现各种各样炫酷的效果,在实现这吊炸天效果的同时,我们往往会定义很多attr属性,这样就可以在XML中配置我们想 ...
- Android Preference 设置偏好全攻略
Android 设置是每个App必不可小的东西,看似很简单,但是初学不熟悉的很花时间去研究,特别样式兼容方面,以及有自定义设置的需求,下面是对用法做一个总结 Preference结构 界面结构看下图 ...
- android 几个工具方法
集合几个工具方法,方便以后使用. 1.获取手机 分辨率屏幕: public static void printScreenInfor(Context context){ DisplayMetrics ...
- Unity Shader学习笔记 - 用UV动画实现沙滩上的泡沫
这个泡沫效果来自远古时代的Unity官方海岛Demo, 原效果直接复制3个材质球在js脚本中做UV动画偏移,这里尝试在shader中做动画并且一个pass中完成: // Upgrade NOTE: r ...