题目链接

Problem Description

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.

Input

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$$$.

 
Output

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.

 
Sample Input

3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4

 
Sample Output

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的更多相关文章

  1. hdu6312 2018杭电多校第二场 1004 D Game 博弈

    Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. 【2020杭电多校】Distinct Sub-palindromes 找规律

    题目链接:Distinct Sub-palindromes 题意: 给你一个长度n,你需要找出来一些串,这些串由A...Z和a...z构成.我们设长度为n的所有串中所包含回文子串最少的数量为ans.问 ...

  3. 2018 杭电多校3 - M.Walking Plan

    题目链接 Problem Description There are $$$n$$$ intersections in Bytetown, connected with $$$m$$$ one way ...

  4. 2018 杭电多校1 - Chiaki Sequence Revisited

    题目链接 Problem Description Chiaki is interested in an infinite sequence $$$a_1,a_2,a_3,...,$$$ which i ...

  5. 2018 杭电多校2 - Naive Operations

    题目链接 Problem Description In a galaxy far, far away, there are two integer sequence a and b of length ...

  6. 2018杭电多校第二场1003(DFS,欧拉回路)

    #include<bits/stdc++.h>using namespace std;int n,m;int x,y;int num,cnt;int degree[100007],vis[ ...

  7. 2018杭电多校第六场1009(DFS,思维)

    #include<bits/stdc++.h>using namespace std;int a[100010];char s[20];int zhiren[100010];vector& ...

  8. 2018杭电多校第五场1002(暴力DFS【数位】,剪枝)

    //never use translation#include<bits/stdc++.h>using namespace std;int k;char a[20];//储存每个数的数值i ...

  9. 2018杭电多校第三场1003(状态压缩DP)

    #include<bits/stdc++.h>using namespace std;const int mod =1e9+7;int dp[1<<10];int cnt[1& ...

随机推荐

  1. [原创]用python实现系统状态监测和故障转移

    #coding: utf-8 import socket import select import time import os import threading def ser(): s = soc ...

  2. Java线程和多线程(十二)——线程池基础

    Java 线程池管理多个工作线程,其中包含了一个队列,包含着所有等待被执行的任务.开发者可以通过使用ThreadPoolExecutor来在Java中创建线程池. 线程池是Java中多线程的一个重要概 ...

  3. Codevs1332_上白泽慧音_KEY

    题目传送门 裸的模板题,Tarjan求联通量.  code: #include <cstdio> #include <vector> #define min(a,b) a< ...

  4. 【caffe范例详解】 - 1.Classification分类

    1. 安装 首先,导入numpy和matplotlib库 # numpy是常用的科学计算库,matplot是常用的绘图库 import numpy as np import matplotlib.py ...

  5. MySQL - 问题集 - Access denied; you need the SUPER privilege for

    当执行存储过程相关操作时,如果出现该错误,则往下看. 打开存储过程,会发现“CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost`”. 由于DEFI ...

  6. docker in docker

    docker run --rm可以从一个镜像启动容器,并在容器执行完成后自动删除,这在计算任务中非常有用. 例如,我们通过以下步骤完成计算任务容器的启动: 1 将输入数据通过卷挂载方式连接到计算任务容 ...

  7. 「日常训练」COMMON 约数研究(HYSBZ-1968)

    题意与分析 感谢https://www.cnblogs.com/Leohh/p/7512960.html的题解.这题话说原来不在我的训练范围,正好有个同学问我,我就拿来做做.数学果然不是我擅长的啊,这 ...

  8. 项目实战:BBS+Blog项目开发

    01-博客系统之功能需求 02-博客系统之表结构设计1 03-博客系统之表结构设计2 04-博客系统之表结构设计3 05-博客系统之表结构设计4 06-博客系统之表机构设计5 07-博客系统之创建系统 ...

  9. 在deepin系统中制作桌面快捷方式

    在使用deepin-wine 安装一些软件的时候,每次启动都需要到.deepinwine目录下运行deepin-wine xx.exe.笔者在安装过HeidiSql之后,一直苦于这种情况.比较好的解决 ...

  10. Qt+opencv:读取、显示图像

    GitHub:点击下载完整代码 本文主要是使用Qt与opencv将图像进行显示在QT界面上. 程序运行后的界面如下所示: (由于只有打开图像之后,才能对图像进行翻转,所以程序设置为读取图像成功之后才能 ...