CF798E. Mike and code of a permutation [拓扑排序 线段树]
CF798E. Mike and code of a permutation
题意:
排列p,编码了一个序列a。对于每个i,找到第一个\(p_j > p_i\)并且未被标记的j,标记这个j并\(a[i]=j\)。给出a求一个可行的p,保证有解。\(n \le 500000\)
令\(b(i) = a^{-1}(i)\),也就是说\(b_i\)表示i被谁标记了
容易想到把小于关系用边表示然后拓扑排序
将没有的a和b置为n+1
我们从题目中能直接得到两种小于关系:\((i,b_i)\),以及\(j \in [1,a_i-1], b_j > i, j \neq i\)
第二种关系可以用线段树得到
但我们不能遍历所有边,否则会退化成\(O(n^2)\)
所以使用dfs式的拓扑排序,dfs到一个节点时直接将他从线段树中删除(也就是删除了他的所有入边)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
#define mid ((l+r)>>1)
#define lc x<<1
#define rc x<<1|1
#define lson lc, l, mid
#define rson rc, mid+1, r
#define pii pair<int, int>
#define fir first
#define sec second
const int N = 5e5+5;
inline int read(){
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, a[N], b[N], vis[N];
namespace S {
pair<int, int> t[N<<2];
void build(int x, int l, int r) {
if(l == r) t[x] = make_pair(b[l], l);
else {
build(lson);
build(rson);
t[x] = max(t[lc], t[rc]);
}
}
pii que(int x, int l, int r, int ql, int qr) {
if(ql<=l && r<=qr) return t[x];
else {
if(qr <= mid) return que(lson, ql, qr);
if(mid < ql) return que(rson, ql, qr);
return max(que(lson, ql, qr), que(rson, ql, qr));
}
}
void del(int x, int l, int r, int p) {
if(l == r) t[x] = make_pair(0, l);
else {
if(p <= mid) del(lson, p);
else del(rson, p);
t[x] = max(t[lc], t[rc]);
}
}
}
int q[N], m, p[N];
void dfs(int u) {
vis[u] = 1;
S::del(1, 1, n, u);
if(b[u] != n+1 && !vis[b[u]]) dfs(b[u]);
if(a[u] > 1) while(true) {
pii v = S::que(1, 1, n, 1, a[u]-1);
if(v.fir > u) dfs(v.sec);
else break;
}
q[++m] = u;
}
int main() {
//freopen("in", "r", stdin);
n = read();
for(int i=1; i<=n; i++) {
a[i] = read();
if(a[i] != -1) b[a[i]] = i;
else a[i] = n+1;
}
for(int i=1; i<=n; i++) if(!b[i]) b[i] = n+1;
S::build(1, 1, n);
for(int i=1; i<=n; i++) if(!vis[i]) dfs(i);
m = 0;
for(int i=1; i<=n; i++) p[q[i]] = ++m;
for(int i=1; i<=n; i++) printf("%d ", p[i]);
}
CF798E. Mike and code of a permutation [拓扑排序 线段树]的更多相关文章
- Nowcoder Hash Function ( 拓扑排序 && 线段树优化建图 )
题目链接 题意 : 给出一个哈希表.其避免冲突的方法是线性探测再散列.现在问你给出的哈希表是否合法.如果合法则输出所有元素插入的顺序.如果有多解则输出字典序最小的那一个.如果不合法则输出 -1 分析 ...
- P3588 [POI2015]PUS(拓扑排序+线段树)
P3588 [POI2015]PUS 对于每个$(l,r,k)$,将$k$个位置向剩下$r-l-k+1$个位置连边,边权为$1$,这样就保证$k$个位置比剩下的大 先给所有位置填$1e9$保证最优 然 ...
- Luogu5289 十二省联考2019字符串问题(后缀数组+拓扑排序+线段树/主席树/KDTree)
先考虑80分做法,即满足A串长度均不小于B串,容易发现每个B串对应的所有A串在后缀数组上都是一段连续区间,线段树优化连边然后判环求最长链即可.场上就写了这个. 100分也没有什么本质区别,没有A串长度 ...
- hdu 5638 Toposort (拓扑排序+线段树)
Toposort Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- hdu 5195 DZY Loves Topological Sorting (拓扑排序+线段树)
DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 ...
- [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)
[Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和) E. Permuta ...
- HDU 4917 Permutation 拓扑排序的计数
题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以 ...
- 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)
3832: [Poi2014]Rally Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 168 Solved: ...
- [BZOJ2815][ZJOI2012]灾难(拓扑排序/支配树)
支配树目前只见到这一个应用,那就不独分一类,直接作为拓扑排序题好了. 每个点向所有食物连边,定义fa[x]为x的支配点,即离x最近的点,满足若fa[x]灭绝,则x也要灭绝. 这样,将fa[x]向x连边 ...
随机推荐
- hdu_1042(模拟大数乘法)
计算n! #include<cstring> #include<cstdio> using namespace std; ]; int main() { int n; whil ...
- 【新版】Android技术博客精华汇总
[新版]Android技术博客精华汇总(原文链接内持续更新) http://www.apkbus.com/thread-313856-1-1.html Kotlin Kotlin学习资料汇总 http ...
- c++(数据选择)
在数学中,有一些数据选择的内容.举个例子来说,有这样一组数据:1.2.3.4.现在我们打算从中挑选出1个数据,那么有几种选择呢?结果应该是1.2.3.4:那么如果挑选2个数据呢,怎么选呢?那么结果应该 ...
- JAVA爬虫实践(实践三:爬虫框架webMagic和csdnBlog爬虫)
WebMagic WebMagic是一个简单灵活的Java爬虫框架.基于WebMagic,你可以快速开发出一个高效.易维护的爬虫. 采用HttpClient可以实现定向的爬虫,也可以自己编写算法逻辑来 ...
- [数据库] SQL查询语句表行列转换及一行数据转换成两列
原文来自:http://blog.csdn.net/Eastmount/article/details/50559008 本文主要讲述了SQL查询语句表之间的行列转换,同时也包括如何将一行数据转换成两 ...
- DEDECMS首页调用图片集里的多张图片
本文给大家分享的是织梦系统中首页调用图片集里的多张图片的方法,有相同需要的小伙伴可以参考下. 先找到include/common.inc.php文件,把下面代码贴进去(我贴的是我网站上的,具体可根据需 ...
- 怎么从一台电脑的浏览器输入地址访问另一台电脑服务器(WAMP服务器已搭建,PHPSTORM装好了)
服务器电脑WAMP环境搭建好了,浏览器输入LOCALHOST就能访问本地 WAMP/WWW 目录下PHP文件,怎么样才能从另一台电脑通过浏览器访问呢?求详细步骤... glwbdtb | 浏览 180 ...
- Uva 12171 Sculpture - 离散化 + floodfill
题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- php错误 分析
---------------------------------------------------------------------------------------------------- ...
- SQLServer导出数据表结构
SELECT (case when a.colorder=1 then d.name else '' end)表名, a.colorder 字段序号, a.name 字段名, (case when C ...