转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

ZZX and Permutations

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 181    Accepted Submission(s): 38

Problem Description
ZZX likes permutations.

ZZX knows that a permutation can be decomposed into disjoint cycles(see https://en.wikipedia.org/wiki/Permutation#Cycle_notation). For example:
145632=(1)(35)(462)=(462)(1)(35)=(35)(1)(462)=(246)(1)(53)=(624)(1)(53)……
Note that there are many ways to rewrite it, but they are all equivalent.
A cycle with only one element is also written in the decomposition, like (1) in the example above.

Now, we remove all the parentheses in the decomposition. So the decomposition of 145632 can be 135462,462135,351462,246153,624153……

Now you are given the decomposition of a permutation after removing all the parentheses (itself is also a permutation). You should recover the original permutation. There are many ways to recover, so you should find the one with largest lexicographic order.

 



Input
First line contains an integer t, the number of test cases.
Then t testcases follow. In each testcase:
First line contains an integer n, the size of the permutation.
Second line contains n space-separated integers, the decomposition after removing parentheses.

n≤105. There are 10 testcases satisfying n≤105, 200 testcases satisfying n≤1000.

 



Output
Output n space-separated numbers in a line for each testcase.
Don't output space after the last number of a line.
 



Sample Input
2
6
1 4 5 6 3 2
2
1 2
 



Sample Output
4 6 2 5 1 3
2 1

和题解的解法几乎一致,然而却在比赛结束后才意识到自己跪在了一个傻逼的地方,真是2333333

贪心,先放第一个位置,放尽可能大的值,然后依次往后,对于每个值,看其后面的一个位置,或者前面没有使用过的连续区间

 //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
int Scan() {
int res=, ch;
while(ch=getchar(), ch<''||ch>'');
res=ch-'';
while((ch=getchar())>=''&&ch<='')
res=res*+ch-'';
return res;
}
void Out(int a) {
if(a>)
Out(a/);
putchar(a%+'');
}
int a[];
int vis[];
int pos[];
int fa[];
int dp[];
int ans[];
set<int> ms;
int n;
set<int>::IT it;
int find(int x){
if(fa[x]!=x)fa[x] = find(fa[x]);
return fa[x];
}
void push_up(int cur){
dp[cur] = max(dp[cur<<],dp[cur<<|]);
}
void build(int l,int r,int cur){
if(l==r){
dp[cur] = a[l];
return;
}
int mid = (l+r)>>;
build(l,mid,cur<<);
build(mid+,r,cur<<|);
push_up(cur);
}
void update(int l,int r,int cur,int x,int inc){
if(l==r&&l==x){
dp[cur] = inc;
return;
}
int mid = (l+r)>>;
if(x<=mid)update(l,mid,cur<<,x,inc);
else update(mid+,r,cur<<|,x,inc);
push_up(cur);
}
void update(int x,int num){
update(,n,,x,num);
}
int query(int l,int r,int lx,int rx,int cur){
if(l>=lx&&r<=rx)return dp[cur];
if(lx>r||rx<l)return ;
int mid = (l+r)>>;
return max(query(l,mid,lx,rx,cur<<),query(mid+,r,lx,rx,cur<<|));
}
int query(int l,int r){
return query(,n,l,r,);
}
int main(){
int t;
t = Scan();
while(t--){
n = Scan();
for(int i = ;i<=n;i++){
a[i] = Scan();
vis[i] = ;
pos[a[i]] = i;
fa[i] = i;
}
for(int i=;i<=*n;i++)dp[i] = ;
build(,n,);
ms.clear();
ms.insert();
ms.insert(-INF);
for(int i=;i<=n;i++){
if(vis[i])continue;
int l;
int posi = pos[i];
int maxx = find(i);
int p =pos[maxx];
if(posi+<=n&&!vis[a[posi+]]){
if(a[posi+]>maxx){
p = posi+;
maxx = a[p];
}
}
if(posi>){
it = ms.upper_bound(-posi);
l = *it;
l = -l;
l++;
int tmp = query(l,posi);
//tmp = find(tmp);
//cout<<l<<" "<<tmp<<endl;
if(tmp>maxx){
maxx = tmp;
p = pos[tmp];
}
}
if(p==posi){
ans[i] = i;
vis[i] = ;
ms.insert(-posi);
}else if(p==posi+){
fa[maxx] = fa[i];
//ans[posi] = maxx;
update(p,);
}else{
ans[i] = a[p];
vis[a[p]] = ;
for(int j=p+;j<=posi;j++){
ans[a[j-]] = a[j];
vis[a[j]] = ;
}
ms.insert(-posi);
}
/* cout<<i<<" "<<p<<" "<<maxx<<endl;
for(int i=1;i<=n;i++){
cout<<ans[i]<<" ";
}
cout<<endl;*/
}
for(int i=;i<=n;i++){
if(i!=)putchar(' ');
Out(ans[i]);
}
puts("");
}
return ;
}

hdu5338 ZZX and Permutations(贪心、线段树)的更多相关文章

  1. hdu 5338 ZZX and Permutations (贪心+线段树+二分)

    ZZX and Permutations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...

  2. hdu5338 ZZX and Permutations

    hdu5338 ZZX and Permutations 非原创,来自多校题解 不是自己写的,惭愧ing…… 留着以后自己参考…… lower_bound {1,2,4,5} 询问 2,返回的是 2 ...

  3. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  4. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  5. Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)

    题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...

  6. poj 2010 Moo University - Financial Aid (贪心+线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 骗一下访问量.... 题意大概是:从c个中选出n个 ...

  7. Codeforces 626G Raffles(贪心+线段树)

    G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input ou ...

  8. UVALive 8519 Arrangement for Contests 2017西安区域赛H 贪心+线段树优化

    题意 等价于给一个数列,每次对一个长度为$K$的连续区间减一 为最多操作多少次 题解: 看样例猜的贪心,10分钟敲了个线段树就交了... 从1开始,找$[i,i+K]$区间的最小值,然后区间减去最小值 ...

  9. BZOJ1828[USACO 2010 Mar Gold 2.Barn Allocation]——贪心+线段树

    题目描述 输入 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数C_i * 第N+2到N+M+1行: 第i+N+1行表示2个整数 A_i和B_i 输出 * 第一行: ...

随机推荐

  1. centos卸载自带的apache(httpd)

    .[root@localhost etc]# rpm -qa|grep httpd,查看与httpd相关软件包. httpd--.el5_2.CentOS. .然后删除httpd: [root@loc ...

  2. 内核参数优化之1 keepalive解析

    以下信息纯属虚构,切勿相信! tcp/ip协议中有一个keep-alive机制,即检查空连接的时效性,当一个空连接持续一段时间后,就会发送一个keep-alive探测包,来探测客户端是否还存在. 如果 ...

  3. 判断Python输入是否为数字

    在接收raw_input方法后,判断接收到的字符串是否为数字 例如: str = raw_input("please input the number:") if str.isdi ...

  4. pyqt5通过文本对话框打开文件

    点击按钮,打开文本对话框,找一人文件,打开并显示内容 QFIleDialog                                                              ...

  5. http://www.cnblogs.com/zhuli19901106/p/4356419.html

    http://www.cnblogs.com/zhuli19901106/p/4356419.html

  6. Ubuntu-Java-Scala-Spark-IEDA-configure

    最近要接触数据分析,需要快速入门,就想在Ubuntu下配置IDEA和Spark编程环境. 1.下载jdk #java /etc/profile .zshrc, 或者直接在终端输入export JAVA ...

  7. 关于split splice slice 的一些事

    学的知识很久不用总会忘记,更何况这三个的拼写都差不多,在这里特意写下自己的一些见解,以便以后可以更好地理解. slice  : 定义:接收一个或两个参数,它可以创建一个由当前数组中的一项或多项组成的新 ...

  8. BZOJ1132: [POI2008]Tro

    1132: [POI2008]Tro Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 815  Solved: 211[Submit][Status] ...

  9. Linux企业级项目实践之网络爬虫(8)——认识URL

    URL是Uniform Resource Location的缩写,译为"统一资源定位符".也可以说,URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和 ...

  10. Hello Bolg!

    初来乍到,将就闹点小情绪吧 博客, 作为一个即将毕业的小码农, 第一次写这东西似乎生涩了点. 而且第一眼看到这东西还觉得特玄乎,不过“化抽象为具体, 化复杂为简单”不正是自己的职业操守吗. 于是, 我 ...