Boring Class HDU - 5324 (CDQ分治)
Here is the problem:
Give you two sequences L1,L2,...,Ln and R1,R2,...,Rn.
Your task is to find a longest subsequence v1,v2,...vm satisfies
v1≥1,vm≤n,vi<vi+1 .(for i from 1 to m - 1)
Lvi≥Lvi+1,Rvi≤Rvi+1(for i from 1 to m - 1)
If there are many longest subsequence satisfy the condition, output the sequence which has the smallest lexicographic order.
InputThere are several test cases, each test case begins with an integer n.
1≤n≤50000
Both of the following two lines contain n integers describe the two sequences.
1≤Li,Ri≤109
OutputFor each test case ,output the an integer m indicates the length of the longest subsequence as described.
Output m integers in the next line.
Sample Input
5
5 4 3 2 1
6 7 8 9 10
2
1 2
3 4
Sample Output
5
1 2 3 4 5
1
1 题意
给你两个序列Li,Ri,求构造一个最长的子序列,使得L递减, R递增。在保证最长的前提下要求字典序最小。(vj)
思路:
很明显的可以看出是三维偏序问题。
但是这题要求的是最长的序列,而不是对于每一个元素求解,所以需要要对CDQ分治的部分做相应的更改。
我们设对每一个元素,求以它未开始的符合题意的序列长度最长是多长。只有这样,才能顺利求出字典序最小。
那么对于每一个元素,在处理其答案时,其右侧的元素答案都应该已知了。
传统分治的做法显然不能满足这个要求,因为在如果先治左边,那么右边未知,便无法知道答案。
于是我们想到先分治右侧,再分治左侧。
但是这还不够,在对左侧求解过程中,当前右侧的答案可能并非是全局的答案,这一点的原因我不知道该如何描述,但是在3层CDQ里面就已经很明显了。
所以我们先分治右边,在处理当前层,再分治左边。
由于分治顺序的特殊性,归并排序已经不适用了,所以只能使用快排。
注意在处理左侧之前,要回复左侧原来的顺序。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) clog<<#x<<" = "<<x<<endl;
#define debug(a, x) clog<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define lson l,mid,ls
#define rson mid+1,r,rs
#define ls (rt<<1)
#define rs ((rt<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int loveisblue = ;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); int n;
struct node{
int a,b,c,ans;
}cdq[maxn];
int mx[maxn<<];
void update(int l,int r,int rt,int pos,int val){
if(l==r){
mx[rt]=val;
return;
}
int mid = (l+r)>>;
if(pos<=mid){
update(lson,pos,val);
}else{
update(rson,pos,val);
}
mx[rt]=max(mx[ls],mx[rs]);
} int query(int l,int r,int rt,int L,int R){
if(L<=l&&R>=r){
return mx[rt];
}
int ans = ;
int mid = (l+r)>>;
if(L<=mid){
ans= max(ans,query(lson,L,R));
}if(R>mid){
ans = max(ans,query(rson,L,R));
}
return ans;
}
int num[maxn];
int rem[maxn],tot;
int get_id(int x){
return lower_bound(rem+,rem++tot,x)-rem;
} bool cmp1(node a,node b){
if(a.b!=b.b)return a.b>b.b;
return a.c<b.c;
}
bool cmp(node a,node b){
return a.a<b.a;
} void solve(int l,int r){
if(l==r){ return;}
int mid = (l+r)>>;
solve(mid+,r);
int t1 = mid,t2 = r;
int cur = r+;
sort(cdq+l,cdq+mid+,cmp1);
sort(cdq+mid+,cdq+r+,cmp1);
while (t1>=l||t2>mid) {
if (t1 < l || (t2 > mid && cdq[t1].b >= cdq[t2].b)) {
update(, tot, , get_id(cdq[t2].c), cdq[t2].ans);
t2--;
} else {
cdq[t1].ans = max(cdq[t1].ans, query(, tot, , get_id(cdq[t1].c) ,tot)+);
t1--;
}
}
for(int i=mid+;i<=r;i++){
update(,tot,,get_id(cdq[i].c),);
}
sort(cdq+l,cdq+mid+,cmp);
solve(l,mid);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while (scanf("%d",&n)!=EOF) {
tot = ;
for (int i = ; i <= n; i++) {
scanf("%d", &num[i]);
}
for (int i = ; i <= n; i++) {
int x;
scanf("%d", &x);
rem[++tot] = x;
cdq[i] = node{i, num[i], x, };
}
sort(rem+,rem++tot);
tot = unique(rem+,rem++tot)-rem-;
solve(,n);
sort(cdq+,cdq++n,cmp);
int ans = ;
for(int i=;i<=n;i++){
ans = max(cdq[i].ans,ans);
}
printf("%d\n",ans);
int last = ;
cdq[].b = inf;
cdq[].c = -;
for(int i=;i<=n;i++){
if(cdq[i].ans==ans&&cdq[i].b<=cdq[last].b&&cdq[i].c>=cdq[last].c){
ans--;
last=i;
if(ans==){printf("%d\n",i);}
else printf("%d ",i);
}
}
}
return ;
}
Boring Class HDU - 5324 (CDQ分治)的更多相关文章
- HDU 5324 Boring Class【cdq分治】
这就是一个三维排序的问题,一维递减,两维递增,这样的问题用裸的CDQ分治恰好能够解决. 如同HDU 4742(三维排序,一个三维都是递增的) 由于最小字典序比較麻烦,所以要从后面往前面做分治.每一个点 ...
- HDU - 5324:Boring Class (CDQ分治&树状数组&最小字典序)
题意:给定N个组合,每个组合有a和b,现在求最长序列,满足a不升,b不降. 思路:三位偏序,CDQ分治. 但是没想到怎么输出最小字典序,我好菜啊. 最小字典序: 我们倒序CDQ分治,ans[i]表 ...
- 2015 Multi-University Training Contest 3 hdu 5324 Boring Class
Boring Class Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- HDU 3507 Print Article(CDQ分治+分治DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp ...
- HDU 5730 Shell Necklace(CDQ分治+FFT)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5730 [题目大意] 给出一个数组w,表示不同长度的字段的权值,比如w[3]=5表示如果字段长度为3 ...
- hdu 3842 Machine Works(cdq分治维护凸壳)
题目链接:hdu 3842 Machine Works 详细题解: HDU 3842 Machine Works cdq分治 斜率优化 细节比较多,好好体会一下. 在维护斜率的时候要考虑x1与x2是否 ...
- hdu 5830 FFT + cdq分治
Shell Necklace Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )
hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...
- 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)
BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...
随机推荐
- 开通了第一个博客,mark一下!
今日上网查询了不同的博客,包括csdn.掘金等,最终决定选择博客园.打算待前端学完后,自己建立一个博客,这段时间内先用博客园记录学习过程.经常总结.更新,相信坚持学习一定可以找到好工作!
- 【To Read】Shortest Palindrome(KMP)
题意:Given a string S, you are allowed to convert it to a palindrome by adding characters in front of ...
- 【Leetcode链表】合并两个有序链表(21)
题目 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1-> ...
- Python基础:07迭代器
迭代器是在版本 2.2 被加入Python 的,它为类序列对象提供了一个类序列的接口.Python 的迭代无缝地支持序列对象,而且它还允许迭代非序列类型,包括用户定义的对象.它的出现,对列表迭代.字典 ...
- python MySQLdb用法,python中cursor操作数据库(转)
数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB. 在TESTDB数据库中您已经创建了表 EMPLOYEE EMPLOYEE表字段为 FIRST_NAME, LAST_N ...
- 10-2 body标签中相关的标签(字体标签,排版标签(div,span),超链接,图片标签)
一 排版标签(div,span) 1块级标签 <!--div:把标签中的内容作为一个块儿来对待(division).必须单独占据一行.--> <!--div标签的属性:--> ...
- 16-1 djanjo介绍
一 web框架的本质 1用户的浏览器(socket客户端) 和 网站的服务器(socket服务端)之间 2 HTTP协议: 1.1 请求(request) 1.2. 响应(response) 3 we ...
- poj1741 树上距离小于等于k的对数 点分治 入门题
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- poj 3159 Candies (dij + heap)
3159 -- Candies 明明找的是差分约束,然后就找到这题不知道为什么是求1~n的最短路的题了.然后自己无聊写了一个heap,518ms通过. 代码如下: #include <cstdi ...
- JS iFrame 加载慢怎么解决
在项目中经常要动态添加iframe,然后再对添加的iframe进行相关操作,有时候会遇到iframe加载很慢什么原因呢,该如何解决呢?带着这个问题一起通过本文学习,寻找答案吧! aaa.html &l ...