D. Zip-line

题目连接:

http://www.codeforces.com/contest/650/problem/D

Description

Vasya has decided to build a zip-line on trees of a nearby forest. He wants the line to be as long as possible but he doesn't remember exactly the heights of all trees in the forest. He is sure that he remembers correct heights of all trees except, possibly, one of them.

It is known that the forest consists of n trees staying in a row numbered from left to right with integers from 1 to n. According to Vasya, the height of the i-th tree is equal to hi. The zip-line of length k should hang over k (1 ≤ k ≤ n) trees i1, i2, ..., ik (i1 < i2 < ... < ik) such that their heights form an increasing sequence, that is hi1 < hi2 < ... < hik.

Petya had been in this forest together with Vasya, and he now has q assumptions about the mistake in Vasya's sequence h. His i-th assumption consists of two integers ai and bi indicating that, according to Petya, the height of the tree numbered ai is actually equal to bi. Note that Petya's assumptions are independent from each other.

Your task is to find the maximum length of a zip-line that can be built over the trees under each of the q assumptions.

In this problem the length of a zip line is considered equal to the number of trees that form this zip-line.

Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 400 000) — the number of the trees in the forest and the number of Petya's assumptions, respectively.

The following line contains n integers hi (1 ≤ hi ≤ 109) — the heights of trees according to Vasya.

Each of the following m lines contains two integers ai and bi (1 ≤ ai ≤ n, 1 ≤ bi ≤ 109).

Output

For each of the Petya's assumptions output one integer, indicating the maximum length of a zip-line that can be built under this assumption.

Sample Input

4 4
1 2 3 4
1 1
1 4
4 3
4 5

Sample Output

4
3
3
4

Hint

题意

给你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)这个很显然……

然后就完了。

细节部分,就是需要离散化一下,然后就没了,感觉还是很好写的。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;int n,m;
int a[maxn],dp1[maxn],dp2[maxn];
typedef int SgTreeDataType;
struct treenode
{int L , R  ;SgTreeDataType sum , lazy;void update(SgTreeDataType v){sum = max(sum,v);}
};
struct Seg
{treenode tree[maxn*4];inline void push_down(int o){}inline void push_up(int o){tree[o].sum = max(tree[2*o].sum , tree[2*o+1].sum);}inline void build_tree(int L , int R , int o){tree[o].L = L , tree[o].R = R,tree[o].sum = 0;if (R > L){int mid = (L+R) >> 1;build_tree(L,mid,o*2);build_tree(mid+1,R,o*2+1);}}inline void update(int QL,int QR,SgTreeDataType v,int o){int L = tree[o].L , R = tree[o].R;if (QL <= L && R <= QR) tree[o].update(v);else{push_down(o);int mid = (L+R)>>1;if (QL <= mid) update(QL,QR,v,o*2);if (QR >  mid) update(QL,QR,v,o*2+1);push_up(o);}}inline SgTreeDataType query(int QL,int QR,int o){int L = tree[o].L , R = tree[o].R;if (QL <= L && R <= QR) return tree[o].sum;else{push_down(o);int mid = (L+R)>>1;SgTreeDataType res = 0;if (QL <= mid) res = max(res, query(QL,QR,2*o));if (QR > mid) res = max(res, query(QL,QR,2*o+1));push_up(o);return res;}}
}L,R;map<int,int> H;
vector<int> P;
struct node
{int x,y;
}Q[maxn];
vector<pair<int,int> > Qx[maxn];
int cnt[maxn];
int dp3[maxn],dp4[maxn];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]),P.push_back(a[i]);for(int i=1;i<=m;i++)scanf("%d%d",&Q[i].x,&Q[i].y),P.push_back(Q[i].y);sort(P.begin(),P.end());P.erase(unique(P.begin(),P.end()),P.end());for(int i=0;i<P.size();i++)H[P[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],Qx[Q[i].x].push_back(make_pair(i,Q[i].y));L.build_tree(1,P.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<Qx[i].size();j++){int id = Qx[i][j].first;int x = Qx[i][j].second;dp3[id]=L.query(1,x-1,1)+1;}L.update(a[i],a[i],dp1[i],1);}reverse(a+1,a+1+n);R.build_tree(1,P.size()+5,1);for(int i=1;i<=n;i++){dp2[i]=R.query(a[i]+1,P.size(),1)+1;for(int j=0;j<Qx[n-i+1].size();j++){int id = Qx[n-i+1][j].first;int x = Qx[n-i+1][j].second;dp4[id]=R.query(x+1,P.size(),1)+1;}R.update(a[i],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);}
}

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

  1. Codeforces Round #285 (Div. 2) D. Misha and Permutations Summation 康托展开 + 线段树

    传送门 文章目录 题意: 思路: 题意: 思路: 首先肯定不能模n!n!n!,所以考虑先将a,ba,ba,b做一个逆康托展开,得到a′,b′a',b'a′,b′数组,以及a′+b′=suma'+b'= ...

  2. Codeforces Round #345 (Div. 2)

    DFS A - Joysticks 嫌麻烦直接DFS暴搜吧,有坑点是当前电量<=1就不能再掉电,直接结束. #include <bits/stdc++.h>typedef long ...

  3. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

    题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...

  4. 【Codeforces Round #532 (Div. 2) F. Ivan and Burgers】离线+线性基

    F. Ivan and Burgers 题意 n个数,q次询问,每次询问一个区间内选出任意个数的异或最大值. 1<=n<=5∗1051<=n<=5*10^51<=n< ...

  5. Codeforces Round #710 (Div. 3)个人题解

    Codeforces Round #710 (Div. 3) 文章目录 [Codeforces Round #710 (Div. 3)](https://codeforces.com/contest/ ...

  6. Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索

    Codeforces Round #297 (Div. 2)E. Anya and Cubes Time Limit: 2 Sec  Memory Limit: 512 MB Submit: xxx  ...

  7. Codeforces Round #297 (Div. 2)C. Ilya and Sticks 贪心

    Codeforces Round #297 (Div. 2)C. Ilya and Sticks Time Limit: 2 Sec  Memory Limit: 256 MB Submit: xxx ...

  8. [CF]Codeforces Round #529 (Div. 3)

    [CF]Codeforces Round #529 (Div. 3) C. Powers Of Two Description A positive integer xx is called a po ...

  9. Codeforces Round #632 (Div. 2)巧用小技巧

    Codeforces Round #632 (Div. 2)点这 Eugene likes working with arrays. And today he needs your help in s ...

最新文章

  1. java selectcommand_“对于不返回任何基表信息的 SelectCommand 不支持动态SQL生成”-奇怪的错误,不知道原因! | 学步园...
  2. asp.net中将枚举绑定到下拉列表
  3. JAVA内存模型及垃圾回收自我总结
  4. 测试面试题集-接口测试
  5. 关于欧几里德第五公设的感言
  6. 【单目标优化求解】基于matlab混沌算法求解单目标问题【含Matlab源码 1410期】
  7. (转)EPWING格式的日语词典
  8. #洛谷oj:P1196银河英雄传说
  9. 企业微信api接口调用-通过手机号或微信好友添加客户
  10. Jcrop+ajaxFileUpload 图片裁切上传 oss(java web)
  11. 嵌入式单片机基础篇(二十三)之串口通信
  12. 【latex入门】基本语法|常见报错
  13. 理解套间(涉及进程、线程、COM线程模型)(转载)
  14. 年产6000t乳制品工厂设计
  15. 我们是如何连上WiFi的?
  16. android 登录注册动画,Android开发(14)——动画实战:炫酷登录
  17. 判断回文数的简便算法
  18. 新乡市牧野区开展2021年国家网络安全宣传周活动
  19. 初识 love2d. Hello World lua 调试 iOS 环境运行
  20. 【NC65】主子表单据按照单表结构展现 节点客开

热门文章

  1. java中BigDicemal的运算
  2. Redlock原理简介和实现过程
  3. iscsiadm及其他磁盘相关命令
  4. Linux命令之basename 命令
  5. 年底了,按约定把2021 Go面试八股整理全了
  6. Redis积分排行榜设计与实现第一篇
  7. Java类加载器( 死磕9)
  8. 利用Linux的强大移植性和兼容性将操作系统轻松安装到硬盘
  9. web单页应用(一)
  10. 基于Rest服务实现的RPC