Codeforces Round 973 (Div. 2) D

性质1:题目操作相当于将前面的数搬到了后面,将其视为柱状图,则是把前面柱的高度转移至后面柱的高度

性质2:最后移成的序列以单调不下降序列为最优,易证明当存在下降时,可通过操作使答案更优或不变差

性质3:由于性质2,易得最佳序列尾部最高,故可以通过栈来维护,其为单调栈,栈口最高

性质4:对于确定的总和sum与某个数(组)的出现次数cnt,由性质2得只有可能有 sum / cnt 与 sum / cnt + 1 两种取值,易得出现sum / cnt + 1次数为sum%cnt

性质5:优先用大的数来平衡每次加入且需要平衡的数

c++ 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2 * 100010 + 10;
int n;
int T;
int f[N];
struct edge
{
	int val;
	int cnt;
};
stack <edge> st;
signed main()
{
	scanf("%lld",&T);
	while(T--)
	{
		while(!st.empty())st.pop();
		scanf("%lld",&n);	
		edge a;
		for(int i = 1;i <= n;i++)
			scanf("%lld",&f[i]);			
		a.val = f[1];
		a.cnt = 1;
		st.push(a);
		for(int i = 2;i <= n;i++)
		{
			a.val = f[i];
			a.cnt = 1;
			while(  !st.empty() && a.val / a.cnt <= st.top().val / st.top().cnt)
			{
				edge b = st.top();
				st.pop();
				a.val += b.val;
				a.cnt += b.cnt;	
			} 
			edge tt;
			tt.val = a.val / a.cnt * (a.cnt - a.val % a.cnt); 
			tt.cnt =  a.cnt - a.val % a.cnt;
			st.push(tt);
			if(a.val % a.cnt > 0)
			{
				tt.val = (a.val / a.cnt + 1) * (a.val % a.cnt);
				tt.cnt = a.val % a.cnt;
				st.push(tt);
			}
		}
		int mx = st.top().val / st.top().cnt;
		int mn = -1;
		while(!st.empty())
		{
			
			mn = st.top().val / st.top().cnt;
			st.pop();
		}
		
		
		printf("%lld\n",mx - mn);
	}	
	return 0; 
} 
相关推荐
Code920074 个月前
Codeforces Round 951 (Div. 2) F. Kostyanych‘s Theorem(思维题 交互好题)
交互·思维题
Code920074 个月前
Codeforces Round 948 (Div. 2) E. Tensor(思维题-交互)
思维题·乱搞ac