hdu5338 ZZX and Permutations(贪心、线段树)
转载请注明出处: 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
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.
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.
Don't output space after the last number of a line.
6
1 4 5 6 3 2
2
1 2
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(贪心、线段树)的更多相关文章
- hdu 5338 ZZX and Permutations (贪心+线段树+二分)
ZZX and Permutations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- hdu5338 ZZX and Permutations
hdu5338 ZZX and Permutations 非原创,来自多校题解 不是自己写的,惭愧ing…… 留着以后自己参考…… lower_bound {1,2,4,5} 询问 2,返回的是 2 ...
- BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库
正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...
- 【题解】P1712 [NOI2016]区间(贪心+线段树)
[题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...
- Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)
题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...
- poj 2010 Moo University - Financial Aid (贪心+线段树)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 骗一下访问量.... 题意大概是:从c个中选出n个 ...
- Codeforces 626G Raffles(贪心+线段树)
G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input ou ...
- UVALive 8519 Arrangement for Contests 2017西安区域赛H 贪心+线段树优化
题意 等价于给一个数列,每次对一个长度为$K$的连续区间减一 为最多操作多少次 题解: 看样例猜的贪心,10分钟敲了个线段树就交了... 从1开始,找$[i,i+K]$区间的最小值,然后区间减去最小值 ...
- 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 输出 * 第一行: ...
随机推荐
- Hadoop学习历程(三、第一个程序)
根据之前的操作,我们已经可以正常的启动Hadoop了,关于真正的集群我会在之后进行说明.现在我们来看一下第一个程序吧 1. 在eclipse上建立一个java项目 2. 将 /usr/hadoop/s ...
- Java并发编程--多线程中的join方法详解
Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...
- JQuery this和$(this)的区别及获取$(this)子元素对象的方法
1.JQuery this和$(this)的区别 相信很多刚接触JQuery的人,很多都会对$(this)和this的区别模糊不清,那么这两者有什么区别呢? 首先来看看JQuery中的 $() 这 ...
- [每日一题JS] 正则表达式
判断字符串是否是这样组成的,第一个必须是字母,后面可以是字母.数字.下划线,总长度为5-20 var reg = /\b[a-zA-Z]{1}[a-zA-Z0-9_]{4,19}\b/; var fl ...
- Netbeans 注释模板配置
工具->模板->展开Java 选中Java类->在编辑器中打开 修改如下: <#if package?? && package != ""& ...
- document.body.scrollTop vs document.documentElement.scrollTop
window.addEventListener("scroll", function () { if (document.body.scrollTop >= window.i ...
- 面试题 43 n 个骰子的点数
; void printfProbability(int number) { ) return; ]; p[] = ]; p[] = ]; memset(p[], , )); memset(p[], ...
- 智能卡安全机制比较系列(二)DS SmartCard
DS Smart Card是飞利浦公司自己开发的一款CPU卡产品,在早期芯片厂商开发自己的COS并进行推广很普遍,现在像英飞凌(前西门子半导体)以及恩智普(前飞利浦半导体)几乎很少推广自己的COS,大 ...
- 从vector容器中查找一个子串:search()算法
如果要从vector容器中查找是否存在一个子串序列,就像从一个字符串中查找子串那样,次数find()与find_if()算法就不起作用了,需要采用search()算法:例子: #include &qu ...
- 如何查找到文件以后,带目录一起拷贝到新的目录? cp --parents source destination
如何查找到文件以后,带目录一起拷贝到新的目录? cp --parents source destination