smoj2020(平衡树优化dp)
来源:互联网 发布:人工智能在制造业应用 编辑:程序博客网 时间:2024/06/08 19:17
依然是比赛遇到的,我打完暴力就一直在发呆,想到大概要用splay,然而那时只剩15min了,果断弃了(去拿外卖)。
对于某天也可以哪里都不去。
看起来就像个dp,直接搞个最水的出来。若同样去i个目的地,显然用时越少越优,故设f[i][j]表示前i个,去j个,最后一个目的地最早在哪一天去。
枚举i,j
对于第i个目的地,可以不去,则
这个dp太粗暴了,不好进行更深入的思考,要一步步简化。
首先第一维可以滚动,状态f[i]就表示去i个目的地的最小天数。
显然f数组是严格单调的。
然后把上面转移方程的max改为分类讨论,就变成了这样
① 找到那个满足 f[p]<l[i],f[p+1]≥l[i]的p,将f[p]改为l[i]。
② 对于所有 l≤f[i]≤r 的i,f[i+1]=f[i+1] 。(splay上实现就是区间加,插入和删除结点)
这里f数组的单调性灰常重要,所以才可以一棵splay搞定。
#include <iostream>#include <fstream>#include <algorithm>#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define mmst(a, b) memset(a, b, sizeof(a))#define mmcp(a, b) memcpy(a, b, sizeof(b))typedef long long LL;const int N=600600,oo=1e9+7;int ans,cnt,n;struct tree{ tree *c[2],*f; int ad,a; int d(){return f->c[1]==this;} void sc(tree *x,int d){(c[d]=x)->f=this;}}nil[N],*root;tree *newtree(int k){ nil->a=nil->ad=0; nil->c[0]=nil->c[1]=nil->f=nil; nil[++cnt]=nil[0]; nil[cnt].a=k; return nil+cnt;}void down(tree *x){ if(x->c[0]!=nil) { x->c[0]->a+=x->ad; x->c[0]->ad+=x->ad; } if(x->c[1]!=nil) { x->c[1]->a+=x->ad; x->c[1]->ad+=x->ad; } x->ad=0;}void work(tree *x){ if(x->f!=nil) work(x->f); down(x);}void zig(tree *x){ tree *y=x->f; int d=x->d(); y->sc(x->c[!d],d); if(y->f==nil) root=x,x->f=nil; else y->f->sc(x,y->d()); x->sc(y,!d);}void splay(tree *x){ work(x); for(tree *y;x->f!=nil;) { y=x->f; if(y->f!=nil) (x->d() ^ y->d()) ? zig(x) : zig(y); zig(x); }}void search(int k){ tree *x,*now=root; while(now!=nil) { if(now->a>=k) { x=now; now=now->c[0]; } else now=now->c[1]; down(now); } splay(x);}void Cut(tree *x){ while(1) { if(x->c[0]!=nil) { down(x->c[0]); zig(x->c[0]); } else if(x->c[1]!=nil) { down(x->c[1]); zig(x->c[1]); } else { x->f->sc(nil,x->d()); splay(x->f); break; } }}void dfs(tree *x){ down(x); if(x==nil) return; dfs(x->c[0]); if(x->a>0&&x->a<oo) ans++; dfs(x->c[1]);}tree *build(int l,int r){ if(l>r) return nil; int mid=(l+r)/2; tree *hy=newtree(oo); hy->sc(build(l,mid-1),0); hy->sc(build(mid+1,r),1); return hy;}int main(){ cin>>n; root=newtree(0); root->sc(build(1,n),1); for(int i=1;i<=n;i++) { int l,r; scanf("%d%d",&l,&r); search(l); root->a++; root->c[1]->a++; root->c[1]->ad++; tree *now=root->c[0]; while(now->c[1]!=nil) { down(now); now=now->c[1]; } down(now); now->sc(newtree(l),1); splay(now->c[1]); search(r+1); root->c[1]->a--; root->c[1]->ad--; Cut(root); } dfs(root); cout<<ans<<endl; return 0;}
阅读全文
0 3
- smoj2020(平衡树优化dp)
- POJ-3017 Cut the Sequence(DP单调队列优化 + 平衡树)
- BZOJ1492:[NOI2007]货币兑换Cash (CDQ分治+斜率优化DP/平衡树维护凸壳)
- Codeforces Round #445 Div1 E:Mod Mod Mod (平衡树优化DP)
- 数位dp(平衡数)
- POJ 3017 Cut the Sequence 【DP+单调队列优化+平衡树】
- 索引--优化数据结构--平衡二叉树(avl)
- 平衡二叉树 ssl 2633 dp
- 2017.1.21测试题 攻略城池 (树型dp+二分+平衡树+启发式合并)
- zoj 2900 DP(线段树优化)
- bzoj1835(线段树优化dp)
- DP(斜率优化)
- AVL(平衡树)
- hdu3709 数位dp(自身平衡的数字)
- #bzoj2933#【重庆市NOIP模拟赛】数据(DP线段树优化 or DP堆优化 + 证明)
- hdu 3480 Division(DP-DP优化)
- HDU 2829 Lawrence(四边形优化dp/斜率优化dp)
- ZJU3349 线段树优化DP
- 机器人项目部分数据本地化——工厂模式+策略模式实现
- 欢迎使用CSDN-markdown编辑器
- 布隆过滤器
- Qt 程序编译时提示:The CDB process terminated
- 第三周 Two Sum
- smoj2020(平衡树优化dp)
- 机器学习中的标准化/归一化
- APUE 第6-9章
- cygwin安装
- 兄弟连LinuxStudyNote(3)-给Linux初学者的建议-服务器管理和运维建议(二)linux各目录的作用
- 如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion
- Java学习笔记(一)Java运行机制及JVM相关
- 编程题目录(待整理)
- HttpURLConnection对象的获取