1109: [POI2007]堆积木Klo

https://lydsy.com/JudgeOnline/problem.php?id=1109

分析:

  首先是dp,f[i]表示到第i个的最优值,f[i]=f[j]+1,(j<i,a[j]<a[i],j-a[j]<i-a[i]),三维偏序,可以cdq+线段树转移。实际上由a[j]<a[i]和j-a[j]<i-a[i]可以推出j<i所以二维偏序,直接LIS。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Node{
int x, c;
bool operator < (const Node &A) const {
return x == A.x ? c > A.c : x < A.x;
}
}A[N];
int f[N]; int main() {
int n = read(), cnt = ;
for (int i = ; i <= n; ++i) {
int x = read();
if (i - x >= )
A[++cnt].x = x, A[cnt].c = i - x;
}
if (cnt == ) {
cout << ; return ;
}
int len = ;
sort(A + , A + cnt + );
f[] = A[].c;
for (int i = ; i <= cnt; ++i) {
if (A[i].x != A[i - ].x && A[i].c >= f[len]) f[++len] = A[i].c;
else {
int p = upper_bound(f + , f + len + , A[i].c) - f;
f[p] = A[i].c;
}
}
cout << len;
return ;
}

LIS

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Node{
int id, x, c;
bool operator < (const Node &A) const {
return c == A.c ? x < A.x : c < A.c;
}
}A[N], B[N];
int f[N], mx; #define Root 1, mx, 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
struct SegmentTree{
int mx[N << ];
SegmentTree() { for (int i = ; i <= ; ++i) mx[i] = -1e9; }
void update(int l,int r,int rt,int p,int v) {
if (l == r) { mx[rt] = v; return ; }
int mid = (l + r) >> ;
if (p <= mid) update(lson, p, v);
else update(rson, p, v);
mx[rt] = max(mx[rt << ], mx[rt << | ]);
}
int query(int l,int r,int rt,int p) {
if (p < ) return -1e9;
if (r <= p) return mx[rt];
int mid = (l + r) >> ;
if (p <= mid) return query(lson, p);
else return max(mx[rt << ], query(rson, p));
}
}T; void cdq(int l,int r) {
if (l >= r) return ;
int mid = (l + r) >> ;
cdq(l, mid);
for (int i = mid + ; i <= r; ++i) B[i] = A[i];
sort(B + mid + , B + r + );
for (int p = l, j = mid + ; j <= r; ++j) {
if (f[B[j].id] == -1e9) continue;
while (p <= mid && A[p].c <= B[j].c) T.update(Root, A[p].x, f[A[p].id]), p ++;
f[B[j].id] = max(f[B[j].id], T.query(Root, B[j].x - ) + );
}
for (int i = l; i <= mid; ++i) T.update(Root, A[i].x, ); // B[i].x!!!
cdq(mid + , r);
sort(A + l, A + r + );
} int main() {
int n = read();
for (int i = ; i <= n; ++i) {
A[i].x = read(), A[i].id = i, A[i].c = i - A[i].x;
if (A[i].x <= i) f[i] = ;
else f[i] = -1e9;
mx = max(mx, A[i].x);
}
cdq(, n);
int ans = ;
for (int i = ; i <= n; ++i) ans = max(ans, f[i]);
cout << ans;
return ;
}

CDQ

1109: [POI2007]堆积木Klo的更多相关文章

  1. BZOJ 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 948  Solved: 341[Submit][Statu ...

  2. BZOJ 1109 [POI2007]堆积木Klo(树状数组)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1109 [题目大意] Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体. ...

  3. bzoj 1109 [POI2007]堆积木Klo(LIS)

    [题意] n个数的序列,删除一个数后序列左移,求最后满足i==a[i]的最大个数. [思路] 设最终得到a[i]==i的序列为s,则s应满足: i<j,a[i]<a[j],i-a[i]&l ...

  4. 【BZOJ】1109: [POI2007]堆积木Klo

    题意 \(n(1 \le n \le 100000)\)个数放在一排,可以一走一些数(后面的数向前移),要求最大化\(a_i=i\)的数目. 分析 分析容易得到一个dp方程. 题解 \(d(i)\)表 ...

  5. BZOJ 1109 POI2007 堆积木Klo LIS

    题目大意:给定一个序列,能够多次将某个位置的数删掉并将后面全部数向左串一位,要求操作后a[i]=i的数最多 首先我们如果最后a[i]=i的数的序列为S 那么S满足随着i递增,a[i]递增(相对位置不变 ...

  6. BZOJ.1109.[POI2007]堆积木Klo(DP LIS)

    BZOJ 二维\(DP\)显然.尝试换成一维,令\(f[i]\)表示,强制把\(i\)放到\(a_i\)位置去,现在能匹配的最多数目. 那么\(f[i]=\max\{f[j]\}+1\),其中\(j& ...

  7. 【BZOJ1109】[POI2007]堆积木Klo 二维偏序

    [BZOJ1109][POI2007]堆积木Klo Description Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔 ...

  8. 【bzoj1109】[POI2007]堆积木Klo 动态规划+树状数组

    题目描述 Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔.妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置 ...

  9. BZOJ1109 : [POI2007]堆积木Klo

    f[i]表示第i个在自己位置上的最大值 则f[i]=max(f[j])+1 其中 j<i a[j]<a[i] a[i]-a[j]<=i-j -> j-a[j]<=i-a[ ...

随机推荐

  1. BZOJ 1059 矩阵游戏 二分图匹配

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1059 题目大意: 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏 ...

  2. BZOJ2330:[SCOI2011]糖果(差分约束)

    Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的 ...

  3. VSCode调试C++

    在ubuntu下调试C++ 本人觉得VSCode比较好用. 步骤如下: 1. 编写.cpp,.h文件 自行完成自己的程序. 2. 编写CMakeLists.txt.下面是一个比较好用的模板. 根目录为 ...

  4. saltstack安装配置(yum)

    主机规划: (主)master:192.168.25.130 (从)minion:192.168.25.131     192.168.25.132 1.yum安装: 服务端:安装master yum ...

  5. centos 清除yum缓存

    No package nginx available. yum makecache yum install epel-release yum install nginx

  6. 安卓混合开发——原生Java和H5交互,保证你一看就懂!

    ** 在Android开发中,越来越多的商业项目使用了Android原生控件与WebView进行混合开发,当然不仅仅就是显示一个WebView那么简单,有时候还需要本地Java代码与HTML中的Jav ...

  7. Xcode 创建 支持IOS4.3以上版本的应用的方法

    如果是Xcode 5的话步骤为 点击项目名称->Build Settings->搜索 Architectures 这个里面的原始的值是Standard architectures(armv ...

  8. iOS TabBarItem设置红点(未读消息)

    实现原理: 其实是自定义一个view,将view添加到UITabBar上面,也可以是一个按钮,设置背景图片,和label.废话少说直接上代码搞一个UITabBar的分类 #import <UIK ...

  9. 洛谷P4602 [CTSC2018]混合果汁(主席树)

    题目描述 小 R 热衷于做黑暗料理,尤其是混合果汁. 商店里有 nn 种果汁,编号为 0,1,\cdots,n-10,1,⋯,n−1 . ii 号果汁的美味度是 d_idi​ ,每升价格为 p_ipi ...

  10. jQuery属性操作之.val()函数

    目录 .val()实例方法的三种用法 .val()函数源码 调用形式:$('xxx').val(); 调用形式:$('xxx').val(value); 调用形式:$('xxx').val(funct ...