首页 > 其他 > 详细

[CF1392F] Omkar and Landslide - 结论,构造

时间:2020-10-04 09:56:01      阅读:65      评论:0      收藏:0      [点我收藏+]

Description

现在有一些山发生了山体滑坡,这些山从左到右依次排布,第 \(i\) 座山的高度为 \(h_i\),且 \(\forall i\in [1,n),h_i<h_{i+1}\)。每一轮滑坡中,假如变化前的 \(h_i+2\leq h_{i+1}\),那么两座山的高度会发生变化,即 \(h_i+1,h_{i+1}-1\),本轮中所有位置的变化是同时的。问无穷轮后,每座山的高度是多少。

Solution

先讨论问题的三个性质:①操作的顺序无关性;②末态下相邻差不超过 \(1\);③末态下相邻相等的对数不超过 \(1\)

Proof. 考虑这样一种方法,每次取第 \(i\) 个元素开始向左推进,若 \(i=1\) 或者 \(h_i - h_{i-1}<2\) 则结束,否则修改 \(h_i,h_{i-1}\) 并继续向左推进。
在这样一轮推进中,若 \(i\) 左侧的数字各不相同,则会一直推进到 \(1\),这样可能会使得相等的对数增加 \(1\);否则,推进操作会在 \(i+1\) 的右边结束,可能会使得相等对数减少 \(1\)

于是 \(S=\sum h_i\)\(n\) 两个参数即确定了一个唯一的答案序列。

暴力构造这个答案序列的方法是:从序列 \(0,1,2,...,n-1\) 开始,每次暴力对序列的一个尽可能长的前缀增加 \(1\)

结论为

\[a_i = (i-1)+[\frac {s-\frac {n(n-1)}{2}} n] + [i<({(s-\frac {n(n-1)}{2})} \mod n)] \]

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;

int n,a[N],s;

signed main()
{
    ios::sync_with_stdio(false);

    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];

    for(int i=1;i<=n;i++) s+=a[i];

    for(int i=1;i<=n;i++)
    {
        int tmp=(i-1)+(s-n*(n-1)/2)/n+(i<=((s-n*(n-1)/2)%n));
        cout<<tmp<<" ";
    }
    cout<<endl;

    return 0;
}

[CF1392F] Omkar and Landslide - 结论,构造

原文:https://www.cnblogs.com/mollnn/p/13766421.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!