BZOJ 1367: [Baltic2004]sequence
来源:互联网 发布:mysql 排序 编辑:程序博客网 时间:2024/05/29 14:23
思考这道题目的时候毫无思路,而且数据范围很像是贪心题啊。其实我们可以考虑一些极端的情况,如何这个t序列就是递增的,那个直接zi=ti就好了,如果这个序列是递减的,我们可以让z序列全部等于t序列的中位数,这样显然是最优的。(证明略)但题目中z序列递增,所以做一个变换,让所有的zi-i,这样就保证递增了。接下来我们将递减序列进行合并,最后得到的就都是递增序列,直接赋值就好了,在将递减序列合并的时候,还要对应地合并这些序列的中位数,这项操作如何快速完成呢?想到利用可并堆(真不好想啊…),堆里存放的是这个序列前一半的元素,两个堆合并时保留合并的大序列的前一半元素,但这样好像并不一定得到中位数。比如将5 6 7 8 9和1 2 3 4合并,就得到1 2 5 6 7,但这样的情况并不会发生,因为我们每发现一个递减序列就合并, 很容易证得。
总结一下算法的过程,首先将输入序列进行变换,然后按顺序加入,如何发现存在两个序列的中位数递减,则可以进行合并,最后得到了递增的中位数序列,直接赋值相减。
Tips:absi2011的配对堆比我的左偏树高明得不知道到哪里去了。
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>using namespace std;const int maxn=1000000+10;int l[maxn],r[maxn],root[maxn],a[maxn],w[maxn],left1[maxn],right1[maxn],dis[maxn],v[maxn],n,tot;int num[maxn],cnt[maxn];int merge(int x,int y){ if(!x||!y) return x+y; if(v[x]<v[y]) swap(x,y); r[x]=merge(r[x],y); if(dis[l[x]]<=dis[r[x]]) swap(l[x],r[x]); dis[x]=dis[r[x]]+1; return x;}int top(int x){ return v[x];}void pop(int &x){ x=merge(l[x],r[x]);}int main(){ //freopen("1367.in","r",stdin); //freopen("1367.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i]-=i; } for(int i=1;i<=n;i++) { root[++tot]=i;v[i]=a[i];l[i]=r[i]=dis[i]=0; num[tot]=cnt[tot]=1;left1[tot]=i;right1[tot]=i; while(top(root[tot-1])>top(root[tot])&&tot>1) { tot--;root[tot]=merge(root[tot],root[tot+1]); num[tot]+=num[tot+1];cnt[tot]+=cnt[tot+1];right1[tot]=right1[tot+1]; while(cnt[tot]>(num[tot]+1)/2) { pop(root[tot]); cnt[tot]--; } } } long long ans=0; for(int i=1;i<=tot;i++) for(int j=left1[i];j<=right1[i];j++) ans+=abs(top(root[i])-a[j]); printf("%lld\n",ans); return 0;}
0 0
- 【BZOJ 1367】 [Baltic2004]sequence
- BZOJ 1367: [Baltic2004]sequence
- [BZOJ 1367][Baltic2004]sequence
- BZOJ 1367 [Baltic2004]sequence
- bzoj 1367: [Baltic2004]sequence
- BZOJ 1367: [Baltic2004]sequence 左偏树
- BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)
- BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)
- BZOJ 1367 [Baltic2004]sequence 可并堆
- BZOJ 1367 [Baltic2004]sequence 解题报告
- bzoj 1367: [Baltic2004]sequence 左偏树+贪心
- 【BZOJ 1367】 [Baltic2004]sequence 可并堆
- BZOJ[1367][Baltic2004]Sequence 可并堆
- [可并堆 中位数] BZOJ 1367 [Baltic2004]sequence
- bzoj 1367: [Baltic2004]sequence(中位数+可并堆)
- BZOJ 1367 [Baltic2004]sequence【脑洞+可并堆
- 1367:[Baltic2004]sequence 左偏树
- [Baltic2004]sequence。。。初学左偏树
- 秦朝地图
- java字符编码
- 乐元素CTO凌聪:弱联网手游如何防作弊?
- OC_04_属性_点语法_MKC
- Android Adapter 源码笔记(3)
- BZOJ 1367: [Baltic2004]sequence
- uexQQ插件学习心得
- 手把手教你---进程资源分配
- PHP中保留key值把value置0,嵌套数组可用
- 在struts2框架中实现手动处理输入验证
- 【Java总结】static,静态代码块
- C#操作符??和?:
- ACDREAM 03G ACdream的高速公路(贪心专场)
- unity脚本的一些笔记(一)