题目传送门:https://www.nowcoder.com/acm/contest/142/J

题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法。

分析:

eg.对于序列{7,8,16},插入后为{16, -1, -1, -1, -1, -1, -1, 7, 8}。(即,依次插入7,8,16。而插入16时发现7已经被占,所以依次考虑(h(x)+1)%n ,因此16放在0的位置上。)这是正向插入,问题是给一个最终序列,问插入序列。

通过对hash表的观察可以得到:

一个区间里的数一定比单独一个数插入更早。

1.存在答案:

那么就会存在对于每一个数a[i],存在两个位置s=a[i]%n,即本应该放在的位置。和t=i,即实际放在的位置。

朴素O(n^2)建图:

每找到一个数字s!=t,那么向前建边。若s==t,不需要建边。然后每次选择度数为0的点中最小的数(保证字典序min),然后把与该点相连的所有边删去。

通过上述朴素建图,发现每个点所建边的是一段区间内的所有点。引出:

线段树O(n)优化建图:

同上,若一个点需要连向一个区间,就向线段树上的这个区间连边。然后把度数为0的点一一删去,即把线段树内对应的叶子节点清空,然后向上更新。当一个区间为空时,就把所有连向这个点的所有边删掉了。

ps.一个点最多会向线段树上logn个区间,即logn个点相连。

2.判断不合法:

在区间[s,t)内存在-1,即序列不合法。

或拓扑排序出现环。

 #include <bits/stdc++.h>
#define maxn 200005
using namespace std;
typedef pair<int,int> pii;
int fix[maxn],a[maxn];
int pos[maxn<<],id[maxn<<];
int deg[maxn<<];
vector<int> G[maxn<<];
int n;
void init(int n){
memset(deg,,sizeof(int)*(n<<|));
for (int i=;i<(n<<|);i++) G[i].clear();
}
void addedge(int u,int v){
G[u].push_back(v);
deg[v]++;
}
void build(int root,int l,int r){
id[root]=-;
if (l==r){
pos[l]=root;
id[root]=l;
return ;
}
int mid=(l+r)/;
addedge(root<<,root);
addedge(root<<|,root);
build(root<<,l,mid);
build(root<<|,mid+,r);
}
int judge(int s,int t){
if (s<=t) return (fix[t]-fix[s]==) && (a[s]!=-);
else return (fix[n-]-fix[s-]==) && !fix[t];
}
void Addedge(int L,int R,int p,int root,int l,int r){
if (L<=l && r<=R){
addedge(root,p);
return ;
}
int mid=(l+r)/;
if (L<=mid) Addedge(L,R,p,root<<,l,mid);
if (R>mid) Addedge(L,R,p,root<<|,mid+,r);
}
void topo(){
priority_queue<pii,vector<pii>,greater<pii> > Q;
for (int i=;i<n;i++)
if (!deg[pos[i]]) Q.push({a[i],pos[i]});
vector<int> ans;
while (!Q.empty()){
pii pos=Q.top();
Q.pop();
int u=pos.second;
if (pos.first!=-) ans.push_back(pos.first);
int v;
for (auto v : G[u]){
if (--deg[v]==){
if (id[v]==-) Q.push({-,v});
else Q.push({a[id[v]],v});
}
}
}
if (ans.size()!=n-fix[n-]){
cout << - << endl;
return ;
}
if (ans.size()==){
cout << endl;
return ;
}
for (int i=;i<ans.size();i++){
if (i==) cout << ans[i];
else cout << " " << ans[i];
}
cout << endl;
return ;
}
int main(){
int t;
cin >> t;
while (t--){
cin >> n;
init(n);
for (int i=;i<n;i++){
cin >> a[i];
if (i) fix[i]=fix[i-]+(a[i]==-);
else fix[i]=(a[i]==-);
}
int flag=;
for (int i=;i<n;i++){
if (a[i]!=- && !judge(a[i]%n,i)){
cout << - << endl;
flag=;
break;
}
}
if (flag) continue;
build(,,n-);
for (int i=;i<n;i++){
if (a[i]!=-){
int s=a[i]%n,t=i;
if (s==t) continue;
if (s<t){
Addedge(s,t-,pos[i],,,n-);
}
else{
if (t) Addedge(,t-,pos[i],,,n-);
Addedge(s,n-,pos[i],,,n-);
}
}
}
topo();
}
return ;
}

牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)的更多相关文章

  1. 2018牛客多校第四场 J.Hash Function

    题意: 给出一个已知的哈希表.求字典序最小的插入序列,哈希表不合法则输出-1. 题解: 对于哈希表的每一个不为-1的数,假如他的位置是t,令s = a[t]%n.则这个数可以被插入当且仅当第s ~ t ...

  2. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  3. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  4. 2019牛客多校第四场C-sequence(单调栈+线段树)

    sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...

  5. 牛客多校第十场 F Popping Balloons 线段树维护稀疏矩阵

    题意: 给定一个稀疏矩阵,里面有若干个气球,让你横着开三枪,竖着开三枪,问最多能打爆多少气球,要求相同方向,相邻两枪必须间隔r. 题解: 横向记录每列有多少个气球,分别在哪行上. 然后把这个数据改造成 ...

  6. 2019牛客多校第四场J free——分层图&&最短路

    题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...

  7. 牛客多校第四场 J Free 最短路

    题意: 求最短路,但是你有k次机会可以把路径中某条边的长度变为0. 题解: 跑k+1次迪杰斯特拉,设想有k+1组dis数组和优先队列,第k组就意味着删去k条边的情况,每次松弛操作,松弛的两点i,j和距 ...

  8. 2019牛客多校第四场J free 最短路

    free 题意 给出一个带权联通无向图,你需要从s走到t,你可以选择k条变让他们的权值为0问从s到t的最小权值是多少? 分析 思考一下,如果不带k条白嫖这个条件,那么这就是一个简单的dji就搞定了,我 ...

  9. 牛客多校第七场 C Governing sand 线段树

    题意: 有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格.现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费. 题解: 用线段树维护不同种类树的信息,叶子节点从 ...

随机推荐

  1. rsync 目录以 / 结尾 轻松同步数据

    命令:#rsync –avz foo/ bar/ 意义:将 foo 目录之下的所有内容,同步到 bar 目录之下.如果不以斜杠结尾,意义就不同了.

  2. [SoapUI] 获取当前时间包括年月日时分秒来作为命名

    import java.text.SimpleDateFormat GregorianCalendar calendar = new GregorianCalendar() def dateForma ...

  3. httpclient之基本类

    HttpHost类  主机类  主要属性有域名和端口. HttpRoute类  路由类  主要属性有targetHost(目标主要).proxyChain[]代理链 RouteTracker类  和H ...

  4. sublime3中运行python 和设置

    点bulid system建立下面文件 {"cmd":["C:/ProgramData/Anaconda3/python.exe", "-u" ...

  5. 用pyqt5做一个能python程序能插入图片的ide

    之前只是放到github上了,现在一想应该开源,大家想继续做好这个ide的都能从这里起步. #注意在.py文件相同目录下放一个1.png做测试图片 #本质就是用html来实现图片 #写在前面的话:这个 ...

  6. 【转】Hibernate的getSQLQuery方法对char类型的解析问题

    [转]Hibernate的getSQLQuery方法对char类型的解析问题 建立数据库: create table T_TEST1( id char (32), name varchar (255) ...

  7. python的基础操作2

    一 字符串格式化 占位符 %s和%d %s是属于字符串的占位符,而%d是属于数字类型的占位符 #占位符 %s %d # a="我叫%s,年龄%d,就是一个%s"%("al ...

  8. Netty学习第三节Netty的入门级学习

    1.原生NIO存在哪些缺陷     (1)NIO的类库和API繁杂,使用也比较麻烦,需要熟练掌握selector.ServerSocketChannel.SocketChannel.ByteBuffe ...

  9. js函数预编译

    function fn(a){ console.log(a); var a = 123; function a(){} console.log(a); var b = function(){} con ...

  10. 修改Python IDLE代码配色及语法高亮主题

    初学Python,想必大家拿来练习最多的IDE就是Python自带的IDLE了,但是默认的代码配色及语法高亮主题确实很不适应,所以我们需要做个小小的美化,比如像下面这样我做的美化配置: HOW TO ...