【IOI2014】bzoj4367 holiday
来源:互联网 发布:windows只能进安全模式 编辑:程序博客网 时间:2024/05/17 21:07
最优方案一定是先向一边走,然后掉头回来,再向另一边走停在最远处,剩下的时间取走一路上的最大值。
我们用
如果知道到达的最远点的话,能取走的位置的个数是确定的。我么可以用主席树查询区间
注意起点位置是不能被两边同时取走的,因此需要特殊处理。好像只有规定往回走的那一边取走起点才是对的,我也不知道为什么。
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100010,maxt=2800000;#define LL long longint rd(){ int x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}int a[maxn],val[maxn],size[maxt],lson[maxt],rson[maxt],rt[maxn],n,s,m,l,tot;LL sum[maxt],f[2][2][250010];void build(int &u,int bro,int L,int R,int x){ u=++tot; size[u]=size[bro]+1; sum[u]=sum[bro]+val[x]; if (L==R) return; int mid=(L+R)/2; if (x<=mid) { build(lson[u],lson[bro],L,mid,x); rson[u]=rson[bro]; } else { lson[u]=lson[bro]; build(rson[u],rson[bro],mid+1,R,x); }}LL qry(int u,int v,int L,int R,int k){ if (k>=size[u]-size[v]) return sum[u]-sum[v]; if (L==R) return k*val[L]; int mid=(L+R)/2; if (k<=size[rson[u]]-size[rson[v]]) return qry(rson[u],rson[v],mid+1,R,k); return sum[rson[u]]-sum[rson[v]]+qry(lson[u],lson[v],L,mid,k-(size[rson[u]]-size[rson[v]]));}LL cal(int f1,int f2,int t,int p){ int u,v,x; if (f1) u=s+f2,v=p; else u=p,v=s-f2; x=t-abs(p-s)*(f2?1:2); if (x<=0||u>v) return 0; return qry(rt[v],rt[u-1],1,l,x);}void solve(int f1,int f2,int L,int R,int l,int r){ if (L>R) return; int mid=(L+R)/2,p=l; LL x; f[f1][f2][mid]=cal(f1,f2,mid,l); for (int i=l+1;i<=r;i++) { x=cal(f1,f2,mid,i); if (x>f[f1][f2][mid]) { p=i; f[f1][f2][mid]=x; } } if (f1) { solve(f1,f2,L,mid-1,l,p); solve(f1,f2,mid+1,R,p,r); } else { solve(f1,f2,L,mid-1,p,r); solve(f1,f2,mid+1,R,l,p); }}int main(){ //freopen("f.in","r",stdin); //freopen("f.out","w",stdout); LL ans=0; n=rd(); s=rd()+1; m=rd(); for (int i=1;i<=n;i++) a[i]=val[i]=rd(); sort(val+1,val+n+1); l=unique(val+1,val+n+1)-val-1; for (int i=1;i<=n;i++) { a[i]=lower_bound(val+1,val+l+1,a[i])-val; build(rt[i],rt[i-1],1,l,a[i]); } solve(0,0,0,m,1,s); solve(0,1,0,m,1,s); solve(1,0,0,m,s,n); solve(1,1,0,m,s,n); for (int i=0;i<=m;i++) { ans=max(ans,f[0][0][i]+f[1][1][m-i]); ans=max(ans,f[0][1][i]+f[1][0][m-i]); } printf("%lld\n",ans);}
阅读全文
1 0
- 【IOI2014】【BZOJ4367】holiday假期
- [bzoj4367][IOI2014]holiday假期
- 【IOI2014】bzoj4367 holiday
- IOI2014 假期(Holiday)
- BZOJ 4367 [IOI2014]holiday假期 分治 主席树
- [决策单调性 分治 主席树] BZOJ 4367 [IOI2014]holiday假期
- holiday
- IOI2014题解
- UOJ#26. 【IOI2014】Game
- bzoj 4364: [IOI2014]wall砖墙
- bzoj 4364: [IOI2014]wall砖墙
- Holiday模板
- hdu1827Summer Holiday
- IOI Holiday
- Day22:holiday
- 【UOJ#26.】【IOI2014】Game 交互题,构造
- [UOJ 25][IOI2014]Wall(裸线段树)
- [BZOJ]4364: [IOI2014]wall砖墙 线段树
- TensorFlow Mini-batching
- C# :excel读取表名,这样获取的表名不会出错
- SpringMVC的执行流程
- JDBC之日期问题
- Executor框架
- 【IOI2014】bzoj4367 holiday
- Zynq-Linux移植学习笔记之18-Zynq下NOR_FLASH挂载文件系统
- Random的nextInt(int i)方法的返回值
- 安卓学习ViewPager配合ListView实现功能
- AI会不会取代人类?
- node.js使用(二):获取电脑CPU和内存
- 通过-Xlinker、-Wl给链接器传递链接选项
- Angel
- 前端挑战之js编程题(1)