Codeforces #345 div1 D. Zip-line LIS dp
来源:互联网 发布:怎么连接台湾的网络 编辑:程序博客网 时间:2024/06/07 06:36
题目
题目链接:http://codeforces.com/contest/650/problem/D
题目来源:http://codeforces.com/contest/650
简要题意:求改变某位置后的LIS,每次改变相互独立。
题解
真没想到LIS能玩这么多的花样。
修改一个点后经过这个位置的LIS只要排序下询问然后扫两遍就行了。
比较难求的是改变了一个位置的值后不经过改变的位置的LIS,求出后两者最大值就是结果了。
一个结论就是后面那个值不是LIS_LEN就是LIS_LEN-1。
更进一步就是如果当前位置在所有LIS中就是LIS_LEN-1否则就是LIS_LEN。
做法具体是去求当前结尾的最长LIS和当前开头的最长LIS。通过两者之和是否为LIS_LEN+1判断是否在LIS中,如果在LIS中的位置只能出现在某个固定位置则这个位置的值属于所有LIS,可以对以该位置结尾的LIS的长度记数看是否只出现一次。
代码
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define fi first#define se secondusing namespace std;typedef long long LL;typedef pair<int,int> PII;// headconst int N = 4e5+5;const int INF = 0x3f3f3f3f;struct Query { int a, b, no, ans;};bool cmp(const Query &a, const Query &b) { return a.a < b.a;}bool cmp2(const Query &a, const Query &b) { return a.no < b.no;}Query q[N];int a[N];int lis[N], l[N], r[N];bool all[N];int cnt[N];int n, m;int getPos(int x) { return lower_bound(lis, lis + n, x) - lis;}int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d", a+i); } for (int i = 0; i < m; i++) { scanf("%d%d", &q[i].a, &q[i].b); q[i].a--; q[i].no = i; } sort(q, q + m, cmp); memset(lis, INF, sizeof lis); int last = 0; for (int i = 0; i < n; i++) { while (last < m && q[last].a == i) { q[last++].ans += getPos(q[last].b); } int pos = getPos(a[i]); lis[pos] = a[i]; l[i] = pos + 1; } int lislen = lower_bound(lis, lis + n, INF) - lis; memset(lis, INF, sizeof lis); last = m-1; for (int i = n-1; ~i; i--) { while (last >= 0 && q[last].a == i) { q[last--].ans += getPos(-q[last].b); } int pos = getPos(-a[i]); lis[pos] = -a[i]; r[i] = pos + 1; } for (int i = 0; i < n; i++) { if (l[i] + r[i] != lislen + 1) continue; cnt[l[i]]++; } for (int i = 0; i < n; i++) { if (l[i] + r[i] != lislen + 1) continue; all[i] = (cnt[l[i]] == 1); } sort(q, q + m, cmp2); for (int i = 0; i < m; i++) { printf("%d\n", max(q[i].ans + 1, lislen - all[q[i].a])); } return 0;}
0 0
- Codeforces #345 div1 D. Zip-line LIS dp
- Codeforces Zip-line 650D 345Div1D(LIS)
- [DP] codeforces 650D. Zip-line
- Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
- codeforces 650 D. Zip-line
- codeforces 650d Zip-line
- Codeforces Round #345 (Div. 1) D. Zip-line
- Codeforces Round #345 (Div. 1) D. Zip-line
- Codeforces 650D. Zip-line (动态LIS) (可持久化线段树 或 离线+树状数组)
- codeforces-div1-282-D
- codeforces-div1-284-D
- codeforces-div1-286-D
- codeforces-div1-285-D
- codeforces 250 div1 D
- Codeforces round339 div1 D
- Codeforces #383 div1 D
- codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
- CodeForces 650D Zip-line(最长上升子序列)
- Codeforces 631E:Product Sum
- C# 使用keybd_event()函数模拟键盘按键
- 【BZOJ1044】【tyvj3511】【codevs1870】木棍分割,二分答案+滚动数组+前缀和DP
- 【译】UNIVERSAL IMAGE LOADER.PART 2---ImageLoaderConfiguration详解
- kmeans++算法流程
- Codeforces #345 div1 D. Zip-line LIS dp
- Equipment uva1508
- 从两个有序数组的并集中寻找第k小元素
- bzoj 1085 骑士精神
- 删除算法 2-remove_copy()
- MRC到ARC的自动转换
- 第二周项目4-用循环求
- HTML5初探
- winform textBox输入提示