题目链接

题目的意思很简单, 就是给你n个数, m个询问, 每次询问修改某一个位置的值, 然后问你修改完之后数列的lis是多少。 询问独立。

对于原数列, 我们将它离散化, 令dp1[i]为以i为结尾位置的最长上升子序列的长度, dp[2]为以i结尾的从后往前的最长下降子序列的长度。

原数列的lis显然为max(dp1[i]+dp2[i]-1)。

然后我们求出哪些位置是关键位置, 所谓关键位置, 就是说如果把这个位置的值改变, 那么lis的值也许就会减1。  求关键位置的方法看代码。

然后对于每个询问, 令x[i]为位置, y[i]为修改后并离散化的值,我们令dp3[i]表示将x[i]位置修改为y[i]之后, 以x[i]结尾的最长上升子序列的长度, dp4[i]为最长下降的长度。

那么对于每次询问, 如果x[i]是关键节点, ans[i] = max(lis-1, dp3[i]+dp4[i]-1), 否则的话, ans[i] = max(lis, dp3[i]+dp4[i]-1)。

具体的可以看代码。

还有一点要注意的是数组不能开成4e5, 要开成8e5。

  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <map>
  8. #include <set>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <bitset>
  13. using namespace std;
  14. #define pb(x) push_back(x)
  15. #define ll long long
  16. #define mk(x, y) make_pair(x, y)
  17. #define lson l, m, rt<<1
  18. #define mem(a) memset(a, 0, sizeof(a))
  19. #define rson m+1, r, rt<<1|1
  20. #define mem1(a) memset(a, -1, sizeof(a))
  21. #define mem2(a) memset(a, 0x3f, sizeof(a))
  22. #define rep(i, n, a) for(int i = a; i<n; i++)
  23. #define fi first
  24. #define se second
  25. typedef pair<int, int> pll;
  26. const double PI = acos(-1.0);
  27. const double eps = 1e-;
  28. const int mod = 1e9+;
  29. const int inf = ;
  30. const int dir[][] = { {-, }, {, }, {, -}, {, } };
  31. const int maxn = 8e5+;
  32. int sum[maxn<<], num[maxn], dp1[maxn], dp2[maxn], dp3[maxn], dp4[maxn], a[maxn], b[maxn];
  33. int x[maxn], y[maxn], ans[maxn];
  34. vector <pll> v[maxn];
  35. void update(int p, int val, int l, int r, int rt) {
  36. if(l == r) {
  37. sum[rt] = max(sum[rt], val);
  38. return ;
  39. }
  40. int m = l+r>>;
  41. if(p<=m)
  42. update(p, val, lson);
  43. else
  44. update(p, val, rson);
  45. sum[rt] = max(sum[rt<<],sum[rt<<|]);
  46. }
  47. int query(int L, int R, int l, int r, int rt) {
  48. if(L>R)
  49. return ;
  50. if(L<=l&&R>=r) {
  51. return sum[rt];
  52. }
  53. int m = l+r>>, ret = ;
  54. if(L<=m)
  55. ret = query(L, R, lson);
  56. if(R>m)
  57. ret = max(ret, query(L, R, rson));
  58. return ret;
  59. }
  60. int main()
  61. {
  62. int n, m, cnt = ;
  63. cin>>n>>m;
  64. for(int i = ; i<=n; i++) {
  65. scanf("%d", &a[i]);
  66. b[cnt++] = a[i];
  67. }
  68. for(int i = ; i<m; i++) {
  69. scanf("%d%d", &x[i], &y[i]);
  70. b[cnt++] = y[i];
  71. v[x[i]].pb(mk(i, y[i]));
  72. }
  73. sort(b, b+cnt);
  74. cnt = unique(b, b+cnt)-b;
  75. for(int i = ; i<=n; i++) {
  76. a[i] = lower_bound(b, b+cnt, a[i])-b+;
  77. }
  78. for(int i = ; i<=n; i++) {
  79. dp1[i] = query(, a[i]-, , cnt, )+;
  80. for(int j = ; j<v[i].size(); j++) {
  81. int tmp = v[i][j].fi;
  82. int tmpy = lower_bound(b, b+cnt, v[i][j].se)-b+;
  83. dp3[tmp] = query(, tmpy-, , cnt, )+;
  84. }
  85. update(a[i], dp1[i], , cnt, );
  86. }
  87. mem(sum);
  88. for(int i = n; i>=; i--) {
  89. dp2[i] = query(a[i]+, cnt, , cnt, )+;
  90. for(int j = ; j<v[i].size(); j++) {
  91. int tmp = v[i][j].fi;
  92. int tmpy = lower_bound(b, b+cnt, v[i][j].se)-b+;
  93. dp4[tmp] = query(tmpy+, cnt, , cnt, )+;
  94. }
  95. update(a[i], dp2[i], , cnt, );
  96. }
  97. int maxx = ;
  98. for(int i = ; i<=n; i++) {
  99. maxx = max(dp1[i]+dp2[i]-, maxx); //求原数列lis
  100. }
  101. for(int i = ; i<=n; i++) {
  102. if(dp1[i]+dp2[i]- == maxx) {
  103. num[dp1[i]]++; //如果num[dp1[i]] == 1, 那么它就是关键节点
  104. }
  105. }
  106. for(int i = ; i<m; i++) {
  107. int tmp = maxx;
  108. if(dp1[x[i]]+dp2[x[i]]- == maxx && num[dp1[x[i]]] == ) {
  109. tmp--;
  110. }
  111. tmp = max(tmp, dp3[i]+dp4[i]-);
  112. ans[i] = tmp;
  113. }
  114. for(int i = ; i<m; i++) {
  115. printf("%d\n", ans[i]);
  116. }
  117. return ;
  118. }

codeforces 650D. Zip-line 线段树的更多相关文章

  1. Buses and People CodeForces 160E 三维偏序+线段树

    Buses and People CodeForces 160E 三维偏序+线段树 题意 给定 N 个三元组 (a,b,c),现有 M 个询问,每个询问给定一个三元组 (a',b',c'),求满足 a ...

  2. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

  5. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  6. CodeForces 228D. Zigzag(线段树暴力)

    D. Zigzag time limit per test 3 seconds memory limit per test 256 megabytes input standard input out ...

  7. Codeforces 626G Raffles(贪心+线段树)

    G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input ou ...

  8. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  9. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  10. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

随机推荐

  1. sql中int字段实现百分比

    首先: 用col*1.00 把int字段隐式转换成decimal类型. 然后: 用 round(col,2)来截取前两个小数前的数据 最后: 用 CONVERT(FLOAT,decimalNum)来转 ...

  2. 图片上传webuploader

    /** * 基于jquery的图片上传控件 */!function ($) { "use strict"; //定义上传事件 var upImgEvent = { fileQueu ...

  3. OC弱语法

    OC是在运行过程中才会检测对象有没有实现相应的方法,所有编译过程只给出警告:可能找不到对应方法: 如果程序在运行过程中出错,就会出现程序闪退:     类方法:类可以直接调用的方法,相当于java中的 ...

  4. OC中文件的操作

    OC中文件操作,在之前的文章中,已经接触到了文件的创建了,但是那不是很具体和详细,这篇文章我们就来仔细看一下OC中是如何操作文件的: 第一.首先来看一下本身NSString类给我们提供了哪些可以操作文 ...

  5. 随记1(#define a 10和const int a=10)

    正是求职笔试旺季,前几天听说有人遇到此题:#define a 10 和const int a=10的区别,废话不多说,下面来解释一下: #define 指令是定义符号常量 const   定义的是常变 ...

  6. 浅谈C中的指针和数组(七)

    现在到揭露数组名本质的时候了,先给出三个结论: (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组: (2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量: ( ...

  7. 让2个并列的div根据内容自动保持同等高度js

    有左右2个并列的div,2个div都不能限定高度.左div为导航,右div为内容.如何能让左div块自动获得和右div块相等的高度? 同时,也有网友提问到“如果右块高度比左块低,会不会导致左块的内容被 ...

  8. Http 请求头中的 Proxy-Connection

    平时用 Chrome 开发者工具抓包时,经常会见到 Proxy-Connection 这个请求头.之前一直没去了解什么情况下会产生它,也没去了解它有什么含义.最近看完<HTTP 权威指南> ...

  9. 解决android开发webservice的发布与数据库连接的问题

    由于app后续开发的需要,移植了两次webservice和数据库,遇到了不少问题,也花费了很多时间,实践告诉我要学会寻找问题的根源,这样才能在开发中节省时间,尽快解决问题!好,废话不多说,转入正题…… ...

  10. [LeetCode][Python]Reverse Integer

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com'https://oj.leetcode.com/problems/reverse ...