$ >Codeforces \space 650 D. Zip-line<$

题目大意 :
有一个长度为 \(n\) 的序列 \(h\) ,\(m\) 次询问,每一次询问求如果把序列中第 \(x\) 元素变成 \(y\) 后的 \(lis\) 长度

\(1 \leq n, m \leq 4 \times 10^5\)

解题思路 :

考虑答案的形态由两部分组成,一部分是包含 \(x\) 的 \(lis\) ,一部分是不包含 \(x\) 的 \(lis\)

前者显然可以维护左右两个 \(dp\) 值然后主席树数一下点,难度在于后者。

对于第二部分,如果 \(x\) 是之前所有 \(lis\) 共有的点,那么第二部分的答案就是 \(lis-1\) ,否则是 \(lis\)

考虑怎么判断一个点是否是所有 \(lis\) 共有,下面先给出方法:

统计每一个点在 \(lis\) 中出现的位置情况,设 \(l[i]\) 表示从左到右以 \(i\) 结尾的 \(lis\) 长度,\(r[i]\) 表示从右到左以 \(i\) 结尾的 \(lis\) 长度,如果 \(l[i]+r[i]-1=lis\),那么 \(i\) 在 \(lis\) 中的出现位置就是 \(l[i]\),记为 \(pos[i]\)

如果说点 \(x\) 在 \(lis\) 中的出现位置 \(z\) 只有 \(x\) 满足 \(pos[x] =z\) ,那么显然 \(x\) 是不能被替代的,其是所有 \(lis\) 共有的点。不然的话必然存在一种方案不经过 \(x\) 到另外一个满足 \(pos[i] = z\) 的点 \(i\) ,因为 \(x\) 在任何方案下不能存在于两个位置,这样的话 \(lis\) 长度就会更长,有矛盾。

所以只需要统计一下每一个 \(i\) 是不是在所有的 \(lis\) 中出现即可,总复杂度 \(O((n+m)logn)\)

某位神仙表示直接上分治 \(O(nlog^2n)\) 就过了

/*program by mangoyang*/
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){int f = 0, ch = 0; x = 0;for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;if(f) x = -x;
}
const int N = 400005;
int h[N], L[N], R[N], g[N], pos[N], tot[N], lis, n, m;struct SegmentTree{int s[N*25], lc[N*25], rc[N*25], rt[N], size;inline SegmentTree(){ memset(s, 127, sizeof(s)); }inline void ins(int &u, int pr, int l, int r, int pos, int x){u = ++size, lc[u] = lc[pr], rc[u] = rc[pr];if(l == r) return (void)(s[u] = min(s[u], x));int mid = l + r >> 1;if(pos <= mid) ins(lc[u], lc[pr], l, mid, pos, x);else ins(rc[u], rc[pr], mid + 1, r, pos, x);s[u] = min(s[lc[u]], s[rc[u]]);}inline int query(int u, int l, int r, int x){if(l == r) return l;int mid = l + r >> 1;if(s[rc[u]] < x) return query(rc[u], mid + 1, r, x);if(s[lc[u]] < x) return query(lc[u], l, mid, x);return 0;}
}S1, S2;
int main(){read(n), read(m);for(int i = 1; i <= n; i++) read(h[i]);for(int i = 1; i <= n; i++) g[i] = inf;for(int i = 1; i <= n; i++){L[i] = lower_bound(g, g + n, h[i]) - g;g[L[i]] = min(g[L[i]], h[i]), lis = Max(lis, L[i]);}for(int i = 0; i <= n; i++) g[i] = 0; g[0] = -inf;for(int i = n; i >= 1; i--){R[i] = lower_bound(g, g + n, -h[i]) - g;g[R[i]] = min(g[R[i]], -h[i]);}for(int i = 1; i <= n; i++)if(L[i] + R[i] - 1 == lis) pos[i] = L[i], tot[pos[i]]++;for(int i = 1; i <= n; i++)S1.ins(S1.rt[i], S1.rt[i-1], 1, n, L[i], h[i]);for(int i = n; i >= 1; i--)S2.ins(S2.rt[i], S2.rt[i+1], 1, n, R[i], -h[i]);for(int i = 1, x, y; i <= m; i++){read(x), read(y); int res = 0;if(x > 1) res += S1.query(S1.rt[x-1], 1, n, y);if(x < n) res += S2.query(S2.rt[x+1], 1, n, -y);printf("%d\n", max(res + 1, (pos[x] && (tot[pos[x]] == 1)) ? lis - 1 : lis));}return 0;
}

转载于:https://www.cnblogs.com/mangoyang/p/9831705.html

Codeforces 650 D. Zip-line相关推荐

  1. 【CodeForces - 349A】Cinema Line (贪心(其实不是贪心),乱搞)

    题干: The new "Die Hard" movie has just been released! There are n people at the cinema box ...

  2. codeforces 431 B Shower Line【暴力】

    题意:给出五个人的编号,分别为 1 2 3 4 5,他们在排队, 最开始的时候,1和2可以交谈,3和4可以交谈 然后1走了之后,2和3交谈,4和5可以交谈 2走了之后,3和4可以交谈, 3走了之后,4 ...

  3. Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树

    D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...

  4. Codeforces Round #300 A. Cutting Banner 水题

    A. Cutting Banner Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/538/pro ...

  5. Codeforces Round #806 (Div. 4)题解

    目录 A. YES or YES? B. ICPC Balloons C. Cypher D. Double Strings A. YES or YES? time limit per test 1 ...

  6. 使用OpenCV搭建违章停车检测系统

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 各位小伙伴大家好,今天将会带领大家一起学习如何搭建一个违章停车检测 ...

  7. PHP 与Python 读取大文件的区别

    php读取大文件的方法 <?php function readFile($file) {# 打开文件$handle = fopen($file, 'rb');while (feof($handl ...

  8. 【CV】使用OpenCV搭建违章停车检测系统

    各位小伙伴大家好,今天将会带领大家一起学习如何搭建一个违章停车检测系统.需要重点说明的是,今天使用的逻辑和判定条件比较难,尤其是他的编程实现.不过小伙伴不要怕,我们提供了项目的开源代码,具体链接如下: ...

  9. android 日期时间类,Android 时间与日期操作类

    获取本地日期与时间 public String getCalendar() { @SuppressLint("SimpleDateFormat") SimpleDateFormat ...

最新文章

  1. Windows Server 2008 R2 配置笔记,密码设置为任意长度,远程桌面终端连接数的设置...
  2. (MS SQL)如何实现相关文章功能(多关键字匹配)
  3. Spring Boot怎么样处理静态资源(静态资源映射规则)_Web开发
  4. Java中使用HashMap,TreeSet和List来实现模拟斗地主的洗牌和发牌的小例子
  5. mysql性能测试工具msyqlslap_mysqlslap工具测试mysql DB的性能
  6. 使用Hybris commerce的promotion rule进行促销活动
  7. *【51nod - 1459】迷宫游戏(记录双向权值的Dijkstra单源最短路)
  8. android车机系统刷机_让我们盘点一下在整个车联网领域,有哪几类玩家?
  9. linux非编工作站,高清EDIUS非编网络系统建设 在线非编系统
  10. 斗鱼弹幕服务器第三方接入协议v1.6.2,GitHub - yyc-dev/douyu-sdk: DouYu-SDK,一个基于斗鱼弹幕API封装的SDK...
  11. python实现语音机器人
  12. java解析MT940报文,swift MT报文解析处理
  13. 数字信号处理(一)时域采样定理
  14. PG Doc:17章1-3小节翻译
  15. 程序员平时如何学习提高技术
  16. 奇迹网页版php,PHP版网站对接奇迹Mu——实现自动注册等功能
  17. 整理了25个Python文本处理案例,收藏!
  18. 二手交易网站 /二手交易平台/二手交易系统
  19. pca图解读_PCA 图像识别 详解(一)
  20. MATLAB仿真判断系统是否为线性时不变系统

热门文章

  1. 微服务中的面向切面编程和更多模式
  2. openGauss 正式开源并成立开源社区
  3. 实现机器学习的循序渐进指南IX ——树回归
  4. java 断点续传 开源_java断点续传后台代码
  5. JDBC操作(基础篇)
  6. 华为linux系统怎么安装爱奇艺,荣耀智慧屏X1怎么安装爱奇艺?怎么安装第三方软件?很简单...
  7. poll函数_如何理解IO多路复用的三种机制Select,Poll,Epoll?
  8. python实现二分法查找_python二分法查找
  9. predict函数 R_RROC三剑客(一)使用R语言手撕ROC曲线
  10. linux三并发进程,linux下用进度条显示三个进程的并发