2018牛客多校第四场 J.Hash Function
题意:
给出一个已知的哈希表。求字典序最小的插入序列,哈希表不合法则输出-1。
题解:
对于哈希表的每一个不为-1的数,假如他的位置是t,令s = a[t]%n。则这个数可以被插入当且仅当第s ~ t-1个数都不为-1且已经插入完成。
那么对于每一个这样的数,需要连t-s条边(s<=t)或者t+n-s条边(s>t)。
总的边数有O(n^2)条。可以用线段树优化建图。最后跑一边拓扑排序。
对于不合法的情况,第s ~ t-1个数存在-1或者拓扑图存在环会导致不合法。
#include <bits/stdc++.h>
using namespace std;
#define P pair<int, int>
const int N = 4e5+;
int t, n;
int cnt, tot;
int ans[N];
int a[N], pre[N];
int pos[N], rt[N<<], deg[N<<];
int head[N<<], nxt[N<<], to[N<<];
priority_queue<P, vector<P>, greater<P> > q;
void add_edge(int u, int v) {
to[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
deg[v]++;
}
void build(int id, int l, int r) {
rt[id] = -;
if(l == r) {
pos[l] = id;
rt[id] = l;
return;
}
int mid = l+r>>;
build(id<<, l, mid);
build(id<<|, mid+, r);
add_edge(id<<, id);
add_edge(id<<|, id);
}
void update(int id, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) {
add_edge(id, v);
return ;
}
int mid = l+r>>;
if(ql <= mid) update(id<<, l, mid, ql, qr, v);
if(qr > mid) update(id<<|, mid+, r, ql, qr, v);
}
int main() {
scanf("%d", &t);
while(t--) {
tot = ;
scanf("%d", &n);
memset(head, -, sizeof(int)*(n<<));
memset(deg, , sizeof(int)*(n<<));
for(int i = ; i < n; i++) {
scanf("%d", &a[i]);
pre[i] = a[i] == -;
if(i) pre[i] += pre[i-];
}
int flag = ;
for(int i = ; i < n; i++) {
if(~a[i]) {
int s = a[i]%n, t = i;
if(s <= t && pre[t]-(s==?:pre[s-]) || s > t && pre[t]+pre[n-]-pre[s-]) {
flag = ;
break;
}
}
}
if(flag) {
puts("-1");
continue;
}
build(, , n-);
for(int i = ; i < n; i++) {
if(~a[i]) {
int s = a[i]%n, t = i;
if(s < t) update(, , n-, s, t-, pos[t]);
if(s > t) {
if(t > ) update(, , n-, , t-, pos[t]);
update(, , n-, s, n-, pos[t]);
}
}
}
P now;
cnt = ;
while(!q.empty()) q.pop();
for(int i = ; i < n; i++) {
if((~a[i]) && deg[pos[i]] == ) q.push(make_pair(a[i], pos[i]));
}
while(!q.empty()) {
now = q.top();
q.pop();
int u = now.second;
if(~rt[u]) ans[++cnt] = now.first;
for(int i = head[u]; ~i; i = nxt[i]) {
if(--deg[to[i]] == ) {
if((~rt[to[i]]) && (~a[rt[to[i]]])) q.push(make_pair(a[rt[to[i]]], to[i]));
else if(rt[to[i]] == -) q.push(make_pair(, to[i]));
}
}
}
if(cnt != n-pre[n-]) {
puts("-1");
continue;
}
for(int i = ; i <= cnt; i++) {
printf("%d", ans[i]);
if(i != cnt) printf(" ");
}
puts("");
}
}
2018牛客多校第四场 J.Hash Function的更多相关文章
- 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)
题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...
- 2019牛客多校第四场J free——分层图&&最短路
题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...
- 牛客多校第四场 J Free 最短路
题意: 求最短路,但是你有k次机会可以把路径中某条边的长度变为0. 题解: 跑k+1次迪杰斯特拉,设想有k+1组dis数组和优先队列,第k组就意味着删去k条边的情况,每次松弛操作,松弛的两点i,j和距 ...
- 2019牛客多校第四场J free 最短路
free 题意 给出一个带权联通无向图,你需要从s走到t,你可以选择k条变让他们的权值为0问从s到t的最小权值是多少? 分析 思考一下,如果不带k条白嫖这个条件,那么这就是一个简单的dji就搞定了,我 ...
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- 牛客多校第3场 J 思维+树状数组+二分
牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...
- 牛客多校第四场 F Beautiful Garden
链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...
- 牛客多校第四场 G Maximum Mode
链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
随机推荐
- android学习十 ActionBar
1.api level大于等于11 支持,或者使用兼容库,但兼容库的问题很多. 2.一个操作栏属于一个活动,并具有其生命周期 3.操作栏分3类:a.选项卡操作栏,b.列表操作栏,c.标准操作栏 4.获 ...
- linux-centos6②
- Python入门编程中的变量、字符串以及数据类型
//2018.10.10 字符串与变量 1. 在输出语句中如果需要出现单引号或者双引号,可以使用转义符号\,它可以将其中的歧义错误解释化解,使得输出正常: 2. 对于python的任何变量都需要进行赋 ...
- python学习笔记04 --------------基本运算符
1.算数运算 + 加 - 减 * 乘 / 除 % 取模(先做除法,然后返回余数) ** 乘方(幂运算) // 取整(相除,然后返回商的整数部分) 2.比较运算(返回布尔值) == ...
- python学习笔记02 --------------基础数据类型
python的基本数据类型: 1.基本数据 1.1. 数字类型 1.1.1 整数 int int() #将括号内内容转化为整数类型. 1.1.2 浮点数 float 1.1.3 复 ...
- mapReduce入门教程
什么是MapReduce MapReduce是Google提出的一个软件架构,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(归纳)&q ...
- Machine Learning笔记整理 ------ (二)训练集与测试集的划分
在实际应用中,一般会选择将数据集划分为训练集(training set).验证集(validation set)和测试集(testing set).其中,训练集用于训练模型,验证集用于调参.算法选择等 ...
- 简析@Resource 和 @Autowired的区别
@Autowird @Autowird 属于spring框架,默认使用类型(byType)进行注入,例如下面代码: @Autowired public IUserService userService ...
- STM32F4 编程手册学习1_编程模型
STM32F4 programming manual_1 1. 处理器模式与特权等级 处理器模式分为以下两种: 线程模式: 用来执行应用软件: 处理器从reset出来时,进入线程模式: CONTROL ...
- [leetcode-658-Find K Closest Elements]
Given a sorted array, two integers k and x, find the k closest elements to x in the array. The resul ...