任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6301

Distinct Values

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5312    Accepted Submission(s): 1823

Problem Description
Chiaki has an array of n positive integers. You are told some facts about the array: for every two elements ai and aj in the subarray al..r (l≤i<j≤r), ai≠ajholds.
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 and m (1≤n,m≤105) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1≤li≤ri≤n).

It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106.

 
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
 
Source
 

题意概括:

需要求一个长度为 N 的序列,要求满足给出的 M 的子区间内不能出现重复的数,要求字典序最小。

解题思路:

一开始直接双指针模拟,但是果断WA,原因就是当前子区间不能的数不一定是连续的,需要记录前面不能使用的数。

后来用了一个标记数组记录所有不能用的数,TL,想想也知道,查询和维护需要时间复杂度太高。

那有什么可以快速维护这些当前可以使用的数,并且把已经使用过的数删除掉的呢?

C++ STL 里 的 set (可以说功能十分强大了,自动升序排序,可查询,删除)

那么如果知道了当前区间不能时候用什么数,能使用什么数,剩下的就是贪心策略了,尽可能地把需要满足条件子区间扩大(大的子区间满足了它所包含的小的子区间肯定也是满足的)。

用一个数组记录当前序列位置 x 所在的区间的最左值即可。

根据这个最左值 pre[x] 就可以判断当前以求的答案序列里 < pre[x] 的数都是可以用来填充当前子区间的。

AC code:

 #include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = 1e5+;
int num[MAXN];
int pre[MAXN];
int ans[MAXN];
set<int>ss;
int N, M;
int main()
{
int l, r;
int T_case;
scanf("%d", &T_case);
while(T_case--){
ss.clear();
scanf("%d %d", &N, &M); //初始化
for(int i = ; i <= N; i++){pre[i] = i; ss.insert(i);}
for(int i = ; i <= M; i++){scanf("%d %d", &l, &r); pre[r] = min(pre[r], l);}
for(int i = N-; i >= ; i--) pre[i] = min(pre[i], pre[i+]);
int p = ;
for(int i = ; i <= N; i++){
while(p < pre[i]){ss.insert(ans[p]);p++;}
ans[i] = *ss.begin();
ss.erase(ans[i]);
} for(int i = ; i <= N; i++){printf("%d", ans[i]);if(i < N) printf(" ");}
puts("");
}
return ;
}

2018 Multi-University Training Contest 1 Distinct Values 【贪心 + set】的更多相关文章

  1. 2018 Multi-University Training Contest 1 Distinct Values(set)

    题意: t组数据,每组数据给定n,m, 表示有m个约束,每个约束包含 x,y ,代表区间 [x, y] 里的数字不能相同. 让你用所有的正整数构成一个长度为 n 的区间,使得这个区间元素顺序的字典序最 ...

  2. Distinct Values(贪心)

    问题 D: Distinct Values 时间限制: 1 Sec  内存限制: 128 MB提交: 13  解决: 5[提交] [状态] [讨论版] [命题人:admin] 题目描述 Chiaki ...

  3. 2018 Nowcoder Multi-University Training Contest 2

    目录 Contest Info Solutions A. run D. monrey G. transform H. travel I. car J. farm Contest Info Practi ...

  4. 2018 杭电多校1 - Distinct Values

    题目链接 Problem Description Chiaki has an array of n positive integers. You are told some facts about t ...

  5. 2018 Nowcoder Multi-University Training Contest 1

    Practice Link J. Different Integers 题意: 给出\(n\)个数,每次询问\((l_i, r_i)\),表示\(a_1, \cdots, a_i, a_j, \cdo ...

  6. 2018 Nowcoder Multi-University Training Contest 5

    Practice Link A. gpa 题意: 有\(n\)门课程,每门课程的学分为\(s_i\),绩点为\(c_i\),要求最多删除\(k\)门课程,使得gpa最高. gpa计算方式如下: \[ ...

  7. 2018 Nowcoder Multi-University Training Contest 10

    Practice Link J. Rikka with Nickname 题意: 给出\(n\)个字符串,要求依次合并两个串\(s, t\),满足将\(t\)合并到\(s\)中变成\(r\),使得\( ...

  8. 2019 Multi-University Training Contest 1 - 1009 - String - 贪心

    不知道错在哪里. 是要把atop改成stop!两个弄混了.感谢自造样例. #include<bits/stdc++.h> using namespace std; typedef long ...

  9. 2015 Multi-University Training Contest 6 hdu 5360 Hiking

    Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

随机推荐

  1. [转]AngularJS 实现 Table的一些操作(示例大于实际)

    本文转自:http://www.cnblogs.com/lin-js/p/linJS.html <!DOCTYPE html> <html> <head> < ...

  2. .net core 第二篇控制台程序项目初步学习

    1. 使用vscode 创建一个控制台程序 创建项目默认创建的项目名称为父级文件夹名称 后面学习下创建的命令各个参数说明 运行项目dotnet run 其他命令SDK 命令:add 将包或引用添加到 ...

  3. [android] 界面的划分

    1.统一界面管理 1.1利用一个activity去管理应用的所有的界面 1.1.1 理解Activity,Window和View之间的关系 1.1.2 避免Activity过多导致的问题, 例如:彻底 ...

  4. CAP理论-解析

          分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值.(等同于所有节点访问同一份最新的数据副本) ...

  5. JSTL数据格式化

    日期表示 <fmt:formatDate value="${DATE1}" pattern="yyyy-MM-dd hh:mm:ss" type=&quo ...

  6. Java从入门到精通——数据库篇Mongo DB GridFS文件系统

    一.概述    GridFS是MongoDB的一种存储机制,用来存储大型二进制文件. 优点: 1.使用GridFS能够简化你的栈.如果已经在使用MongoDB,那么可以使用GridFS来代替独立的文件 ...

  7. C++类继承--基类析构函数加上Virtual

    下面的内容要说明两个问题:1. 基类的析构函数为什么要加上Virtual--防止内存泄露 1. 基类虚构函数无virtual,派生类无法析构,会导致内存泄露 #include <stdio.h& ...

  8. 大规模WEB服务技术

    CPU负载的扩展很简单,增加相同结构的服务器,通过负载均衡来分散. I/O负载的扩展很困难.要考虑局部性.

  9. Java 之数组(4)

    什么是数组: 问:编写代码保存 4 名学生的考试成绩. 答:简单啊,定义 4 个变量呗 问:那“计算全年级 400 名学生的考试成绩”,肿么办 答: ....... 数组,就可以帮助你妥妥的解决问题啦 ...

  10. Android 快速切换到主线程更新UI的几种方法

    此最近看了网上,在子线程更新UI的方法,说法很多,但都不是很全面.在此我争取做到总结的全面一些,希望以后对自己,对大家都有一些帮助. 方法一: view.post(Runnable action) 假 ...