[2015hdu多校联赛补题]hdu5324 Boring Class
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5324
题意:给你一个二维的序列,让你找出最长的第一维升第二维降的子序列(如果多个答案,输出字典序最小)
解:考虑从后往前dp,在u点你需要知道u点之后的比u的第一维小,第二维大的dp最大值
可以用分治枚举u点之后比u的第一维大的点,然后用树状数组查询比u的第二维小的点中dp最大的
具体是:
dp[i]表示以 i 开头的最长子序列,从后往前更新。
更新u点时有u.dp=max(v.dp)+1;v满足v.x<=u.x,v.y>=u.y,且v的在序列中的u的后面
我们用分治枚举u后面y值比u.y大的点v,然后把以v.x为序号v.dp为值插入树状数组中,就可以O(logN)查询到v.x<=u.x的dp最大值了
总时间复杂度:O(N*logN*logN)
/*
* Problem: hdu5324 Boring Class
* Author: SHJWUDP
* Created Time: 2015/8/3 星期一 21:14:55
* File Name: 233.cpp
* State: Accepted
* Memo: 多维变量的后缀区间查询
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int INF=0x7f7f7f7f; const int MaxA=5e4+; struct Node {
int x, y, id;
bool operator<(const Node & rhs) const {
return y<rhs.y;
}
};
struct Hash : vector<int> { //离散化
void prepare() {
sort(begin(), end());
erase(unique(begin(), end()), end());
}
int get(int x) {
return lower_bound(begin(), end(), x)-begin()+;
}
};
struct Fenwick {
int n;
vector<pair<int, int> > c;
void init(int n) {
this->n=n;
c.assign(n+, make_pair(, -INF));
}
int lowbit(int x) {
return x & -x;
}
void modify(int x, pair<int, int> v) {
while(x<=n) {
c[x]=v; x+=lowbit(x);
}
}
void update(int x, pair<int, int> v) {
while(x<=n) {
c[x]=max(c[x], v); x+=lowbit(x);
}
}
pair<int, int> query(int x) {
pair<int, int> res(, -INF);
while(x>) {
res=max(res, c[x]); x-=lowbit(x);
}
return res;
}
} fw; int n;
vector<Node> arr, tmp;
vector<pair<int, int> > dp; //dp[i].pair(以i开头的最长子序列长度, -子序列中下一个位置)
void dc(int l, int r) {
if(l==r) return;
int m=(l+r)>>;
dc(m+, r);
for(int i=l; i<=r; i++) tmp[i]=arr[i];
sort(tmp.begin()+l, tmp.begin()+m+);
sort(tmp.begin()+m+, tmp.begin()+r+);
int pr=r;
for(int i=m; i>=l; i--) {
int cid=tmp[i].id;
while(pr>m && tmp[pr].y>=tmp[i].y) {
fw.update(tmp[pr].x, make_pair(dp[tmp[pr].id].first+, -tmp[pr].id));//将第二维大于当前点的都加到树状数组里面
pr--;
}
dp[cid]=max(dp[cid], fw.query(tmp[i].x));
}
for(int i=m+; i<=r; i++) fw.modify(tmp[i].x, make_pair(, -INF));//用完树状数组后清空
dc(l, m);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif
while(~scanf("%d", &n)) {
arr.resize(n+); tmp.resize(n+);
Hash hash;
for(int i=; i<=n; i++) {
scanf("%d", &arr[i].x);
arr[i].id=i;
hash.push_back(arr[i].x);
}
hash.prepare();
for(int i=; i<=n; i++) arr[i].x=hash.get(arr[i].x);
hash.clear();
for(int i=; i<=n; i++) {
scanf("%d", &arr[i].y);
hash.push_back(arr[i].y);
}
hash.prepare();
for(int i=; i<=n; i++) arr[i].y=hash.get(arr[i].y); fw.init(n+);
dp.assign(n+, make_pair(, -INF));
dc(, n);
pair<int, int> ans(, -INF);
int stPos;
for(int i=; i<=n; i++) {
if(dp[i]>ans) {
ans=dp[i]; stPos=i;
}
}
printf("%d\n", ans.first);
printf("%d", stPos);
for(int i=-ans.second; i!=INF; i=-dp[i].second) printf(" %d", i);
printf("\n");
}
return ;
}
hdu5324
[2015hdu多校联赛补题]hdu5324 Boring Class的更多相关文章
- [2015hdu多校联赛补题]hdu5384 Danganronpa
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:函数f(A, B)定义:A.B为字符串,f(A, B)为A中有多少个不同的B(ex:f(& ...
- [2015hdu多校联赛补题]hdu5302 Connect the Graph
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5302 题意:给你一个无向图,它的边要么是黑色要么是白色,且图上的每个点最多与两个黑边两个白边相连.现在 ...
- [2015hdu多校联赛补题]hdu5301 Buildings
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5301 题目大意:给你一块由1x1方格组成的矩形区域,其中有且仅有一个坏块,现在你要在上面建矩形的房子, ...
- [2015hdu多校联赛补题]hdu5378 Leader in Tree Land
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意:给你一棵n个结点的有根树.因为是有根树,那么每个结点可以指定以它为根的子树(后面讨论的子树 ...
- [2015hdu多校联赛补题]hdu5372 Segment Game
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5372 题意:进行n次操作,操作分两种,0和1,每一个0操作按出现顺序有一个编号(从1开始 0操作 0 ...
- [2015hdu多校联赛补题]hdu5371 Hotaru's problem
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意:把一个数字串A翻过来(abc翻过来为cba)的操作为-A,我们称A-AA这样的串为N-se ...
- [2015hdu多校联赛补题]hdu5303 Delicious Apples
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5303 题意:在一个长为L的环形路径上种着一些苹果树,告诉你苹果树的位置(题目中以0~L指示坐标)及苹果 ...
- [2015hdu多校联赛补题]hdu5299 Circles Game
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5299 题意: 在欧几里得平面上有n个圆,圆之间不会相交也不会相切,现在Alice和Bob玩游戏,两人轮 ...
- [2015hdu多校联赛补题]hdu5348 MZL's endless loop
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5348 题意:给你一个无向图,要你将无向图的边变成有向边,使得得到的图,出度和入度差的绝对值小于等于1, ...
随机推荐
- Apache配置代理服务器的方法(1)
众所周知Apache是目前最优秀的HTTP服务器.实际上它不仅能当作服务器使用,也能够被用来架设代理服务器.本文就如何使用Apache架设HTTP代理服务器进行说明. 本文将基于Win32版的Apac ...
- mysql的ONLY_FULL_GROUP_BY语义 --转自http://www.wtoutiao.com/p/19dh3ec.html
执行SET GLOBAL sql_mode = ''; 把sql_mode 改成非only_full_group_by模式.验证是否生效 SELECT @@GLOBAL.sql_mode 或 SELE ...
- ROC曲线
1.混淆矩阵(confusion matrix) 针对预测值和真实值之间的关系,我们可以将样本分为四个部分,分别是: 真正例(True Positive,TP):预测值和真实值都为1 ...
- eclipse下新建maven项目
eclipse下新建maven项目 1.1下载maven安装包 进入Maven官网的下载页面:http://maven.apache.org/download.cgi,如下图所示:\ 选择当前最新版本 ...
- 【uTenux实验】时间管理(系统时间/周期性处理/警报处理)
1.系统时间管理 系统时间管理函数用来对系统时间进行操作,是OS的一个基础性的东西.个人认为,设置系统时间和获取系统时间对OS来说基本是可有可无的. uTenux提供了三个系统时间相关API.分别用于 ...
- DCM TUTORIAL – AN INTRODUCTION TO ORIENTATION KINEMATICS (REV 0.1)
原英文地址:dcm_tutorial 感觉这篇文章还是很有学习价值的,所以就抽出了一些时间对本文进行的翻译.下面这个好多人用的算法就是一种DCM 滤波器. //==================== ...
- 【学+原】CSS3的2D动画 ——仿NOMOS手表
看CSS3妙味课堂中有一课是介绍如何做钟表界面,然后三根针都能随着时间转动,然后自己在那个简易的版本上做了一些进一部改进. 最关键的知识点应该是transform-origin这个样式,要选对旋转的中 ...
- linux net command /uboot command
1. uboot command 读取寄存器内容 md [内存地址][长度] 修改内存地址 mw [内存地址][长度] 2. linux络命令 -- netstat -a (all)显示所有选项,默 ...
- pl/sql和sql的区别
源地址:https://zhidao.baidu.com/question/187511430.html 1 sql(数据定义语言) 和PL/Sql的区别:答:SQL是结构化查询语言,比较接近自然语言 ...
- logstash 因为jdk版本不对造成索引时间戳失败
版本 logstash 1.5.0 RC2 JDK 1.7.15 Logstash推荐使用JDK 1.7.75 每次启动都是会有部分的数据无法替换日志中的时间戳,导致日志时间戳被认定为当前读取时间. ...