bzoj3173: [Tjoi2013]最长上升子序列
来源:互联网 发布:网络安全意识 责任心 编辑:程序博客网 时间:2024/06/17 18:12
题意
共n次操作,第i次操作在第xi个数后插入数字i并询问当前最长上升子序列。
n<=100000。 这个我也理解错了很多次
题解
前言
如果把原序列弄出来的话,就可以xjb做了,这个十分简单,就不再赘述了。这里我主要说一下怎么把原序列弄出来。当然,弄出来如果用Splay的话,也很简单,我也不说了,我说一下用二分加树状数组的做法。话说我弄这个想了好几个小时,然后看了做法又弄了好久,荒废了一个下午
做法
我们考虑倒着插入所有数
因为能对他的位置造成的,只有在他后面的数,于是我们考虑倒着插入所有的数
然后我们发现,他最终的位置时这样确定的:
如果在比他先插入的数里面,有一个插入的位置比他当前的小,那么他的位置就++。然后用新的位置继续去寻找,这个地方还比较好理解
然后他最后的话一定是到达一个最小的位置,使得在这个位置前面出现的数刚好等于他移动的差值,写成代码就是(get1就是在这个位置之前的)
get1(mid)==mid-a[u]
然后我们神奇地发现他还是可以二分的,这个感性可能很难理解,于是我们要理性地认识一下
我们发现,mid-a[u]其实是一个递增一次函数,且斜率为1
然后get1呢,是一个递增的函数,但是有多快不知道
但是我们可以确定,他mid每次加1,他变化的大小肯定不会超过1,也就是他肯定不会有上面的一次函数优秀
然后我们发现,当在0点的时候前者就是0,后者是-a[u],画成图像是这样的
黑色的是get1,红色的是另外一个
由于斜率的原因,他们至多会重合一段,然后就不再重合了,由于两个都是递增,于是我们就可以愉快地使用二分来找出重合的最小值了
然后这个方法就说完了。。
CODE:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N=100005;int n;int a[N];int s[N];//搞完后的序列int ss[N];int lb (int x){return x&(-x);}int f1[N];int get1 (int x){ int lalal=0; while (x>=1) { lalal+=f1[x]; x-=lb(x); } return lalal;}void change1 (int x,int y){ while (x<=n) { f1[x]+=y; x+=lb(x); }}void prepare(){ for (int u=n;u>=1;u--) { int l=a[u],r=n; while (l<=r) { int mid=(l+r)>>1; if (get1(mid)<=mid-a[u]) r=mid-1,ss[u]=mid; else l=mid+1; } change1(ss[u],1); } for (int u=1;u<=n;u++) s[ss[u]]=u;}int ans[N];//插入这个数的时候的答案int f[N];int get (int x){ int lalal=0; while (x>=1) { lalal=max(lalal,f[x]); x-=lb(x); } return lalal;}void change (int x,int y){ while (x<=n) { f[x]=max(f[x],y); x+=lb(x); }}void solve (){ for (int u=1;u<=n;u++) { ans[s[u]]=get(s[u])+1; change(s[u],ans[s[u]]); } for (int u=2;u<=n;u++) ans[u]=max(ans[u],ans[u-1]); for (int u=1;u<=n;u++) printf("%d\n",ans[u]);}int main(){ scanf("%d",&n); for (int u=1;u<=n;u++) scanf("%d",&a[u]); for (int u=1;u<=n;u++) a[u]++; prepare(); solve(); return 0;}
阅读全文
0 0
- BZOJ3173 [Tjoi2013]最长上升子序列
- [bzoj3173][TJOI2013]最长上升子序列
- 【bzoj3173】: [Tjoi2013]最长上升子序列
- bzoj3173【TJOI2013】最长上升子序列
- bzoj3173: [Tjoi2013]最长上升子序列
- BZOJ3173: [Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列
- bzoj3173: [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列 Treap
- bzoj3173: [Tjoi2013]最长上升子序列
- BZOJ3173 TJOI2013最长上升子序列(Treap+ZKW线段树)
- bzoj3173 [Tjoi2013]最长上升子序列 dp Treap
- BZOJ3173: [Tjoi2013]最长上升子序列 Treap 平衡树
- BZOJ3173: [Tjoi2013]最长上升子序列 Treap+树状数组
- 【bzoj3173】【Tjoi2013】【最长上升子序列】treap+dp二分优化
- BZOJ3173 [Tjoi2013]最长上升子序列(离线处理+Treap+LIS)
- BZOJ3173[最长上升子序列] Treap+LIS
- SSL2775 2017年10月19日提高组 新壳栈
- NOIP模拟 打牌【贪心】
- rtl8169网卡驱动
- Js/es for(let i in Obj)效率分析及优化
- 九度OJ——1028继续畅通工程
- bzoj3173: [Tjoi2013]最长上升子序列
- ConfigReader(五十九)—— RuneConfig
- jqueryrotate--jQuery旋转插件
- 实验二 Linux用户管理
- 高二&高一&初三模拟赛27 总结
- ORA-01541: system tablespace cannot be brought offline; shut down if necessary
- 单线程,多线程,线程池方法大文件指定单词数量统计
- 数据库基本命令
- Android LockSupport 分析