codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
来源:互联网 发布:unity3d接入支付宝sdk 编辑:程序博客网 时间:2024/05/21 06:47
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.
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).
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.
4 41 2 3 41 11 44 34 5
4334
4 21 3 2 63 52 4
43
Consider the first sample. The first assumption actually coincides with the height remembered by Vasya. In the second assumption the heights of the trees are (4, 2, 3, 4), in the third one they are (1, 2, 3, 3) and in the fourth one they are (1, 2, 3, 5).
题意:给你n个数,有q个询问,每一次替换c上的位置为d,问替换后的最长严格上升子序列的长度是多少。
思路:如果普通的替换再查找肯定超时了,所以我们要用线段树来处理。我们设f[i],g[i]分别为以i位置为尾点和起始点的最长严格上升子序列的长度,这个可以用线段树O(nlogn)的复杂度求出来,记录最长上升子序列的长度为maxlen,然后我们再设f1[i],f2[i]表示询问i替换后,询问替换的位置为c,以c位置为尾点和起始点的最长上升子序列长度。接下来我们要判断替换的节点是不是"关键点","关键点"的意思是,如果原来序列没有这个位置的点,那么原来序列的最长上升子序列的长度达不到maxlen。那么这个要怎么判断呢,我们可以开一个数组cnt[i],表示对于一个节点j,以j为尾节点的最长上升子序列的长度为i,且f[j]+g[j]-1==maxlen的这样符合条件的j点的个数总和。对于每一个位置,先判断f[i]+g[i]-1是不是等于maxlen,如果等于maxlen,那么我们就把cnt[f[i]]++。然后对于每一个询问,ans=max(是不是为关键点?maxlen:maxlen-1 ,f1[i]+g1[i]-1 )。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<string>#include<bitset>#include<algorithm>using namespace std;typedef long long ll;typedef long double ldb;#define inf 99999999#define pi acos(-1.0)#define maxn 400050vector<pair<int,int> >ques[maxn]; //<idx,num>int ans[maxn],a[maxn],pos[2*maxn];int f1[maxn],g1[maxn],f[maxn],g[maxn];int cnt[maxn];int c[maxn],d[maxn];struct node1{ struct node{ int l,r,maxlen; }b[8*maxn]; void build(int l,int r,int th) { int mid; b[th].l=l;b[th].r=r; b[th].maxlen=0; if(l==r)return; mid=(l+r)/2; build(l,mid,th*2); build(mid+1,r,th*2+1); } int question(int l,int r,int th) { int mid; if(b[th].l==l && b[th].r==r){ return b[th].maxlen; } mid=(b[th].l+b[th].r)/2; if(r<=mid)return question(l,r,th*2); else if(l>mid)return question(l,r,th*2+1); return max(question(l,mid,th*2),question(mid+1,r,th*2+1) ); } void update(int idx,int num,int th) { int mid; if(b[th].l==idx && b[th].r==idx){ b[th].maxlen=num;return; } mid=(b[th].l+b[th].r)/2; if(idx<=mid)update(idx,num,th*2); else update(idx,num,th*2+1); b[th].maxlen=max(b[th*2].maxlen,b[th*2+1].maxlen); }}L,R;int main(){ int n,m,i,j,tot; while(scanf("%d%d",&n,&m)!=EOF) { int tot=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); tot++;pos[tot]=a[i]; } for(i=1;i<=m;i++){ scanf("%d%d",&c[i],&d[i]); ques[c[i] ].push_back(make_pair(i,d[i] ) ); tot++;pos[tot]=d[i]; } sort(pos+1,pos+1+tot); tot=unique(pos+1,pos+1+tot)-pos-1; L.build(1,tot,1); R.build(1,tot,1); int maxlen,num,t; maxlen=0; for(i=1;i<=n;i++){ for(j=0;j<ques[i].size();j++){ t=lower_bound(pos+1,pos+1+tot,ques[i][j].second)-pos; if(t==1)num=1; else num=L.question(1,t-1,1)+1; f1[ques[i][j].first ]=num; } t=lower_bound(pos+1,pos+1+tot,a[i])-pos; if(t==1)f[i]=1; else f[i]=L.question(1,t-1,1)+1; L.update(t,f[i],1); maxlen=max(maxlen,f[i]); } for(i=n;i>=1;i--){ for(j=0;j<ques[i].size();j++){ t=lower_bound(pos+1,pos+1+tot,ques[i][j].second)-pos; if(t==tot)num=1; else num=R.question(t+1,tot,1)+1; g1[ques[i][j].first ]=num; } t=lower_bound(pos+1,pos+1+tot,a[i])-pos; if(t==tot)g[i]=1; else g[i]=R.question(t+1,tot,1)+1; R.update(t,g[i],1); } for(i=1;i<=n;i++){ cnt[i]=0; } for(i=1;i<=n;i++){ if(f[i]+g[i]-1==maxlen){ cnt[f[i] ]++; } } int ans; for(i=1;i<=m;i++){ if(f[c[i] ]+g[c[i] ]-1==maxlen && cnt[f[c[i] ] ]==1 ){ ans=maxlen-1; } else ans=maxlen; ans=max(f1[i]+g1[i]-1,ans ); printf("%d\n",ans); } } return 0;}/*15 1476 9 32 82 40 91 46 5 12 69 44 97 30 13 294 7313 8414 515 997 4714 324 1211 209 6515 9510 265 252 6211 81*/
- codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
- CodeForces 650D Zip-line(最长上升子序列)
- Codeforces Round #345 (Div. 1) D. Zip-line LIS 离线 离散化 线段树
- Codeforces Round #323 (Div. 2) D LIS 最长上升子序列
- Codeforces Round #345 (Div. 1) D. Zip-line
- Codeforces Round #345 (Div. 1) D. Zip-line
- tju 4071 2D Birds-Shooting Game 线段树+最长上升子序列
- Codeforces 10D LCIS 求最长公共上升子序列及输出这个子序列 dp
- hdu4521 小明系列问题——小明序列 线段树 间隔大于d的最长上升子序列
- 【线段树+O(nlgn)最长上升子序列】HDU 3564
- HDU 3564 Another LIS 线段树+最长上升子序列
- HDU 3308 最长上升连续子序列 (线段树)
- HDU 3564(线段树+最长上升子序列)
- HDU 3308 线段树。。最长连续上升子序列
- BZOJ 3904 最长上升子序列 lkids 线段树
- hdu 3308 线段树-区间连续最长上升子序列
- BZOJ3173 TJOI2013最长上升子序列(Treap+ZKW线段树)
- JZOJ 4920 降雷皇(最长上升子序列、线段树)
- 【Android】SlidingMenu属性详解
- java中File类的使用方法
- CoordinatorLayout、Toolbar、CollapsingToolbarLayout、AppBarLayout和NestedScrollView组合滑动折叠或拉伸Toolbar的demo
- “Microsoft Office Professional Plus 2010在安装中出错”解决办法
- cmake和make
- codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
- 学习嵌入式linux开发板之iTOP-4412 开发板如何操作GPIO
- 完整SQL分页存储过程(支持多表联接)
- 文件夹下的文件遍历-python
- 多线程:下载图片(不用SDWebImage)
- hadoop使用场景
- 哪些函数不能声明为虚函数
- 本地不安装Oracle,plsql远程连接数据库
- 学习osv原理需要操作系统启动流程