题解:CF1392F Omkar and Landslide
UPD 2026/07/23: 被 hack,加入了负数取模。
首先这个
首先,这个序列变为了单调不减,再看到原来的“滑坡”,此时变为了若
我们定义一个“连续段
我们先考虑问题的简化版。
如果只有两个连续段,并且后一个连续段的值比前一个大
手玩一下,我们定义
可以看到,原本较大的连续段好像在向左“传递”,最后两段会交换位置。证明比较容易。设第一段为
考虑若两段的差值不为
第一分钟
第二分钟依次
依次地,这样也会有一个类似于“传递”的过程,并且该过程可能不止在
同样的道理,拓展到多段仍然成立。所有段最后一定会合并为两段,并且前一段比后一段的值大
需要注意的是,我代码中的
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std ;
const int MAXN = 1e6 + 7 ;
int h[MAXN] ;
signed main() {
ios::sync_with_stdio(0) ;
cin.tie(0) ;
cout.tie(0) ;
int n ;
cin >> n ;
int sum = 0 ;
for (int i = 1 ; i <= n ; i ++) {
cin >> h[i] ;
sum += h[i] - i ;
}
int w = sum / n ;
int p = sum % n ;
if (p < 0) p += n , w -- ;
for (int i = 1 ; i <= p ; i ++) {
cout << w + 1 + i << " " ;
}
for (int i = p + 1 ; i <= n ; i ++) {
cout << w + i << " " ;
}
return 0 ;
}