bzoj 3173: [Tjoi2013]最长上升子序列
2017-10-19 20:18
351 查看
题意:
每次将i插入当前第k个数字后面,求最长上升子序列。题解:
假如这题不是插入,而是直接说放到第k位,且保证k不相同,那么就很好做了。设f[i]表示以第i位为结尾的最长上升子序列。
加入一个值时就统计下它前面的最长上升子序列,加1就好了。因为他是最大的,所以显然对其他f值没有影响。
于是关键是怎么求出原序列。
如果强制在线的话直接平衡树无脑上就好了nlogn完全不虚。
但是可以离线,所以有一种很简便,但挺难想的做法。
将给出的序列反过来插入,对于i,假设i+1~n的数都插好了,怎么求i插在哪呢。
考虑二分,i插入的地方为mid,那么i被向后推了mid-X[i]格。换句话说,在已经插入的数中,mid前要有mid-X[i]个数。(因为无论怎么推,数与数间的相对位置是不会变的,所以插入的时候一定就在i前面)。
所以二分的判定条件是:
getsum(mid)<=mid-x
getsum是树状数组求和。
至于为什么满足二分性,可以将两个函数大概的图像画出来,就显然了。
code:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; int a[100010],n,tr[100010]; int lowbit(int x){return x&(-x);} void change(int k,int c) { for(int i=k;i<=n;i+=lowbit(i)) tr[i]=max(tr[i],c); } int get(int k) { int ans=0; for(int i=k;i>=1;i-=lowbit(i)) ans=max(ans,tr[i]); return ans; } void Change(int k,int c) { for(int i=k;i<=n;i+=lowbit(i)) tr[i]+=c; } int getsum(int k) { int ans=0; for(int i=k;i>=1;i-=lowbit(i)) ans+=tr[i]; return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++; for(int i=n;i>=1;i--) { int x=a[i]; int l=a[i],r=n; while(l<=r) { int mid=(l+r)/2; if(getsum(mid)<=mid-x) a[i]=mid,r=mid-1; else l=mid+1; } Change(a[i],1); } int ans=0; memset(tr,0,sizeof(tr)); for(int i=1;i<=n;i++) { int k=a[i],t=get(k-1)+1; ans=max(ans,t);change(k,t); printf("%d\n",ans); } }
相关文章推荐
- BZOJ3173: [Tjoi2013]最长上升子序列
- 【bzoj 3173】[Tjoi2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )
- 【bzoj3173】[Tjoi2013]最长上升子序列
- 【bzoj3173】: [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列(离线处理+Treap+LIS)
- BZOJ3173: [Tjoi2013]最长上升子序列
- [bzoj3173][TJOI2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- bzoj3173 [Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列 Treap
- bzoj3173: [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列
- bzoj3173 [Tjoi2013]最长上升子序列(dp+splay)
- 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)
- bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)
- bzoj3173 [Tjoi2013]最长上升子序列
- [树状数组求第K大][BZOJ 3173][TJOI 2013]最长上升子序列
- [Treap] [LIS] BZOJ[3173] [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列