zoukankan      html  css  js  c++  java
  • luoguP4331 [BOI2004]Sequence 数字序列

    题意

    大力猜结论。

    首先将所有(a_i)变为(a_i-i),之后求不严格递增的(b_i),显然答案不变,最后(b_i)加上(i)即可。

    考虑两种特殊情况:
    1.(a[])是递增的:所有(b_i=a_i)
    2.(a[])是递减的:显然取(a[])的中位数(x),所有(b_i=x)

    现在考虑(a[])一段递增一段递减这样排列,我们可以对每一段递减的(a_i,a_{i+1}...a_{i+k})求出中位数(c_i)

    现在我们的(a[])变成了(c_1,c_2...c_k)的形式,考虑如果还有(c_{i+1}<c_i),我们就合并(i,i+1)两段,求出它们的中位数作为新的一段的值。

    合并求中位数可以用左偏树完成,我们只需要对每一段开一个左偏树,只保留段数的一半个数,每次合并后就暴力弹出。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1000010;
    int n,top;
    ll ans;
    ll a[maxn],b[maxn];
    struct Heap
    {
    	#define lc(p) (heap[p].lc)
    	#define rc(p) (heap[p].rc)
    	#define dis(p) (heap[p].dis)
    	int lc,rc,dis;
    }heap[maxn];
    struct node
    {
    	int root,l,r,size;
    	ll k;
    }sta[maxn];
    int merge(int x,int y)
    {
    	if(!x||!y)return x+y;
    	if(a[x]<a[y])swap(x,y);
    	rc(x)=merge(rc(x),y);
    	if(dis(rc(x))>dis(lc(x)))swap(lc(x),rc(x));
    	dis(x)=dis(rc(x))+1;
    	return x;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]-=i;
    	for(int i=1;i<=n;i++)
    	{
    		sta[++top]=(node){i,i,i,1,a[i]};
    		while(top>1&&sta[top].k<sta[top-1].k)
    		{
    			sta[top-1].root=merge(sta[top-1].root,sta[top].root);
    			sta[top-1].size+=sta[top].size;
    			sta[top-1].r=sta[top].r;
    			while(sta[top-1].size>(sta[top-1].r-sta[top-1].l+1-1)/2+1)
    			{
    				sta[top-1].size--,sta[top-1].root=merge(lc(sta[top-1].root),rc(sta[top-1].root));
    			}
    			top--;
    			sta[top].k=a[sta[top].root];
    		}
    	}
    	for(int i=1;i<=top;i++)
    		for(int j=sta[i].l;j<=sta[i].r;j++)
    			b[j]=sta[i].k,ans+=abs(a[j]-b[j]);
    	printf("%lld
    ",ans);
    	for(int i=1;i<=n;i++)printf("%lld ",b[i]+i);
    	return 0;
    } 
    
  • 相关阅读:
    巨杉数据库多活架构实践
    云数据库架构演进与实践
    语言入门必学的基础知识你还记得么?
    ASP.NET MVC不可或缺的部分——DI及其本质工作分析
    python JoinableQueue在生产者消费者项目中的简单应用
    asp.net core中写入自定义中间件
    终结python协程----从yield到actor模型的实现
    项目开发中使用并发模型常见问题的整理与思考
    LeetCode刷题之合并排序链表
    python学习笔记
  • 原文地址:https://www.cnblogs.com/nofind/p/11985067.html
Copyright © 2011-2022 走看看