Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
来源:互联网 发布:人工智能疾病诊断 编辑:程序博客网 时间:2024/05/21 11:00
题目链接:http://codeforces.com/contest/650/problem/D
题意:
给你n个数,m个询问
每次单点修改,然后问你现在整个序列的lis长度。
修改完之后,要求修改回去。
解法:
询问离线。
我们维护四个东西,dp1[i]表示从1开始到第i个位置的最长上升子序列长度,dp2[i]表示从n开始到第i个位置的最长递减子序列长度。dp3[i]表示第i个询问的那个位置从1开始到第x(即询问的位置)个位置的最长上升子序列长度,dp4[i]表示递减。
假如询问是x,y那么
然后我们判断一下第x个位置是不是lis的关键位置,是的话,ans=lis。否则的话,ans=lis-1。关键位置就是这个位置是全局lis不可替代的一个数。
然后ans = max(ans,dp3[i]+dp4[i]-1)这个很显然……
然后就完了。
//CF 650D#include <bits/stdc++.h>using namespace std;const int maxn = 400050;int n, m, a[maxn], dp1[maxn], dp2[maxn], dp3[maxn], dp4[maxn];///dp1[i]表示从1开始到第i个位置的最长上升子序列长度,dp2[i]表示从n开始到第i个位置的最长递减子序列长度。///dp3[i]表示第i个询问的那个位置从1开始到第x(即询问的位置)个位置的最长上升子序列长度,dp4[i]表示递减。struct Seg{ struct node{ int l, r, maxlen; }T[maxn*10]; void pushup(int rt){ T[rt].maxlen = max(T[rt*2].maxlen, T[rt*2+1].maxlen); } void build(int l, int r, int rt){ T[rt].l = l, T[rt].r = r, T[rt].maxlen = 0; if(l == r) return; int mid = (l+r)/2; build(l, mid, rt*2); build(mid+1, r, rt*2+1); } void update(int pos, int val, int rt){ if(T[rt].l == pos && pos == T[rt].r){ T[rt].maxlen = val; return; } int mid = (T[rt].l + T[rt].r) / 2; if(pos <= mid) update(pos, val, rt*2); else update(pos, val, rt*2+1); pushup(rt); } int query(int L, int R, int rt){ if(L <= T[rt].l && T[rt].r <= R){ return T[rt].maxlen; } else{ int mid = (T[rt].l + T[rt].r) / 2; int res = 0; if(L <= mid) res = max(res, query(L, R, rt*2)); if(mid < R) res = max(res, query(L, R, rt*2+1)); return res; } }}L, R;map <int, int> H;vector <int> V;struct node{ int x, y;}Q[maxn];vector <pair<int, int>> q[maxn]; //<idx, num>int cnt[maxn];int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); V.push_back(a[i]); } for(int i = 1; i <= m; i++){ scanf("%d%d", &Q[i].x, &Q[i].y); V.push_back(Q[i].y); } sort(V.begin(), V.end()); V.erase(unique(V.begin(), V.end()), V.end()); for(int i = 0; i < V.size(); i++) H[V[i]] = i+1; for(int i = 1; i <= n; i++) a[i] = H[a[i]]; for(int i = 1; i <= m; i++){ Q[i].y = H[Q[i].y]; q[Q[i].x].push_back(make_pair(i, Q[i].y)); } L.build(1, V.size()+5, 1); for(int i = 1; i <= n; i++){ dp1[i] = L.query(1, a[i]-1, 1) + 1; for(int j = 0; j < q[i].size(); j++){ int id = q[i][j].first; int x = q[i][j].second; dp3[id] = L.query(1, x-1, 1) + 1; } L.update(a[i], dp1[i], 1); } reverse(a+1, a+n+1); R.build(1, V.size()+5, 1); for(int i = 1; i <= n; i++){ dp2[i] = R.query(a[i]+1, V.size(), 1) + 1; for(int j = 0; j < q[n-i+1].size(); j++){ int id = q[n-i+1][j].first; int x = q[n-i+1][j].second; dp4[id] = R.query(x+1, V.size(), 1) + 1; } R.update(a[i], dp2[i], 1); } int LIS = 0; for(int i = 1; i <= n; i++){ LIS = max(LIS, dp1[i]); } for(int i = 1; i <= n; i++){ if(dp1[i] + dp2[n-i+1] == LIS + 1){ cnt[dp1[i]]++; } } for(int i = 1; i <= m; i++){ int ans = LIS; int x = Q[i].x; if(dp1[x] + dp2[n-x+1] == LIS+1 && cnt[dp1[x]] == 1) ans--; ans = max(ans, dp3[i] + dp4[i] - 1); printf("%d\n", ans); } return 0;}
0 0
- Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
- Codeforces 650D. Zip-line (动态LIS) (可持久化线段树 或 离线+树状数组)
- Codeforces Round #345 (Div. 1) D. Zip-line
- Codeforces Round #345 (Div. 1) D. Zip-line
- codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(离散化+线段树)
- Codeforces Round #271 (Div. 2) E 离散化+线段树
- Codeforces #345 div1 D. Zip-line LIS dp
- Codeforces Zip-line 650D 345Div1D(LIS)
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(线段树+离散化优化DP)
- Codeforces Round #136 (Div. 2) D. Little Elephant and Array 线段树 离线处理
- Codeforces Round #365 (Div. 2) D 线段树+离线 (区间内的数有哪些
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum(离线线段树)
- Codeforces Beta Round #19 D. Points 线段树+离散化离散化
- Codeforces Round #250 (Div. 1) D 线段树
- CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化
- Codeforces Round #323 (Div. 2)D lis
- HDU 4288 && Codeforces 85D (线段树+离散化+离线处理)
- 基于MATLAB图像处理工具箱
- 交叉编译openssl arm平台
- intelli idea 常用插件
- javascript : missing ) after argument list报错
- dijkstra算法JAVA实现
- Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
- PHP语言基础(标记、注释、变量、数组、常量、函数)
- 刷题小记
- 排序算法(四) 基数排序
- python中的metaclass 的精彩解释
- L1-033. 出生年
- app 启动过程
- nosetest 搭建smoke测试用例集
- nio demo