转载请注明出处: 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. ON UPDATE CURRENT_TIMESTAMP

    CREATE TABLE time1 (   id SMALLINT,   time1 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TI ...

  2. 对于js原型和原型链继承的简单理解(第三种,复制继承)

    复制继承:简单理解,就是把父对象上的所有属性复制到自身对象上: function Cat(){ this.climb = function(){ alert("我会爬树"); } ...

  3. jQuery链式操作

    讨论jQuery的文章很多.然而,关于jQuery的链式操作的文章并无多少.好的代码会带来速度的提升.快速渲染和响应意味着更好的用户体验. 下面就来讲讲jQuery的链式操作. 很多时候我们写代码的时 ...

  4. QM项目开发文档整理

    QM项目开发文档整理 前言 在W公司工作4个多月,庆幸接触到的全是"硬"项目,真枪实干,技术.经验.能力都得到了很大提升. QM项目 此项目WEB前端学到的东西很多,对PHP项目的 ...

  5. Blocks(POJ 3734 矩阵快速幂)

    Blocks Input The first line of the input contains an integer T(1≤T≤100), the number of test cases. E ...

  6. Spark学习笔记--stage和task的划分

    https://github.com/JerryLead/SparkInternals/blob/master/markdown/3-JobPhysicalPlan.md stage 和 task 的 ...

  7. DLog 技巧

    #ifdef DEBUG#ifndef DLog# define DLog(fmt, ...) {NSLog((@"%s [Line %d] " fmt), __PRETTY_FU ...

  8. vi使用入门指南

    一.Unix编辑器概述 编辑器是使用计算机的重要工具之一,在各种操作系统中,编辑器都是必不可少的部件.Unix及其相似的ix操作系统系列中,为方便各种用户在各个不同的环境中使用,提供了一系列的ex编辑 ...

  9. hdu3308--LCIS 最大连续递增序列长度

    这个是动态的,所以要用线段树维护.代码里有注释因为ls敲成lsum,rs敲成rsum查错查了好久.. #include <set> #include <map> #includ ...

  10. js设计模式系列之(一)请节约你的请求-代理模式

    What’s the proxy pattern? 代理模式其实就是将违反单一性原则的类给抽离出来,尽量满足开放和封闭的原则. 相当于一个类的行为只是一种,但是你可以给这个类添加额外的行为.比如: 一 ...