bzoj3173 [Tjoi2013]最长上升子序列
2013-05-13 21:49
267 查看
这个题...被恶心到了。
如果插入的数是无序的话,貌似就要做三维偏序了= =,但这个题就不需要了哈。
其实,LIS是可以用bit做的,每次我们可以求出以当前插入的数为结尾的LIS长度,也就是查询x的前缀max,插入的时候把查询结果+1插入bit。我们看到,如果插入的数的递增的话,要么新的LIS是以x结尾,要么不变,于是扫一遍就好了。
但是我们得知道插入数的实际位置,怎么做?有一种比较简单的方法就是倒着扫序列,二分答案+bit,这个bit维护前缀和,也就是求比二分的位置小的数的个数,与插入位置相比。我一开始想的是直接用bit求比插入位置x小的数的个数,但这样是错的,因为插入这个数之前这个数的的位置有可能被顶到了后面,就不能单单用它插入的位置来查询。于是就应该用二分虚拟一个答案mid,通过ask(mid)与mid-x比较来确定实际位置。其实这样做就是替代了平衡树的作用。
sequence
如果插入的数是无序的话,貌似就要做三维偏序了= =,但这个题就不需要了哈。
其实,LIS是可以用bit做的,每次我们可以求出以当前插入的数为结尾的LIS长度,也就是查询x的前缀max,插入的时候把查询结果+1插入bit。我们看到,如果插入的数的递增的话,要么新的LIS是以x结尾,要么不变,于是扫一遍就好了。
但是我们得知道插入数的实际位置,怎么做?有一种比较简单的方法就是倒着扫序列,二分答案+bit,这个bit维护前缀和,也就是求比二分的位置小的数的个数,与插入位置相比。我一开始想的是直接用bit求比插入位置x小的数的个数,但这样是错的,因为插入这个数之前这个数的的位置有可能被顶到了后面,就不能单单用它插入的位置来查询。于是就应该用二分虚拟一个答案mid,通过ask(mid)与mid-x比较来确定实际位置。其实这样做就是替代了平衡树的作用。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define maxn 220000 #define inf 1000000000 using namespace std; int pos[maxn],a[maxn],f[maxn],size[maxn],c[maxn][2],fa[maxn]; int n,m; struct bit { int b[maxn]; void add(int x,int z) { for (int i=x;i<=n;i+=(i&-i)) b[i]+=z; } int ask(int x) { int tmp=0; for (int i=x;i;i-=(i&-i)) tmp+=b[i]; return tmp; } }d; struct bmx { int b[maxn]; void add(int x,int z) { for (int i=x;i<=n;i+=(i&-i)) b[i]=max(b[i],z); } int ask(int x) { int tmp=0; for (int i=x;i;i-=(i&-i)) tmp=max(b[i],tmp); return tmp; } }s; int main() { //freopen("sequence.in","r",stdin); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]+=1; for (int i=n;i;i--) { int l=1,r=n; while (l<=r) { int mid=(l+r)>>1; if (d.ask(mid)<=mid-a[i]) r=mid-1,pos[i]=mid; else l=mid+1; } d.add(pos[i],1); } for (int i=1;i<=n;i++) { f[i]=s.ask(pos[i])+1; s.add(pos[i],f[i]); f[i]=max(f[i],f[i-1]); } for (int i=1;i<=n;i++) printf("%d\n",f[i]); return 0; }
sequence
相关文章推荐
- 【bzoj 3173】[Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列
- BZOJ3173: [Tjoi2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- BZOJ3173: [Tjoi2013]最长上升子序列
- bzoj3173: [Tjoi2013]最长上升子序列
- bzoj 3173: [Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列 Treap
- [树状数组求第K大][BZOJ 3173][TJOI 2013]最长上升子序列
- 【bzoj3173】: [Tjoi2013]最长上升子序列
- bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)
- 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)
- [bzoj3173][TJOI2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )
- bzoj 3173: [Tjoi2013]最长上升子序列(splay)
- [Treap] [LIS] BZOJ[3173] [Tjoi2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列(离线处理+Treap+LIS)
- bzoj3173: [Tjoi2013]最长上升子序列(fhqtreap)