Atcoder 2335 Frequency 题解
Posted xie-dodo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Atcoder 2335 Frequency 题解相关的知识,希望对你有一定的参考价值。
Problem Statement
Snuke loves constructing integer sequences.
There are N piles of stones, numbered 1 through N. The pile numbered i consists of ai stones.
Snuke will construct an integer sequence s of length Σai, as follows:
- Among the piles with the largest number of stones remaining, let x be the index of the pile with the smallest index. Append x to the end of s.
- Select a pile with one or more stones remaining, and remove a stone from that pile.
- If there is a pile with one or more stones remaining, go back to step 1. Otherwise, terminate the process.
We are interested in the lexicographically smallest sequence that can be constructed. For each of the integers 1,2,3,…,N, how many times does it occur in the lexicographically smallest sequence?
Constraints
- 1≤N≤105
- 1≤ai≤109
Input
The input is given from Standard Input in the following format:
N a1 a2 … aN
Output
Print N lines. The i-th line should contain the number of the occurrences of the integer i in the lexicographically smallest sequence that can be constructed.
Sample Input 1
2 1 2
Sample Output 1
2 1
The lexicographically smallest sequence is constructed as follows:
- Since the pile with the largest number of stones remaining is pile 2, append 2to the end of s. Then, remove a stone from pile 2.
- Since the piles with the largest number of stones remaining are pile 1 and 2, append 1 to the end of s (we take the smallest index). Then, remove a stone from pile 2.
- Since the pile with the largest number of stones remaining is pile 1, append 1to the end of s. Then, remove a stone from pile 1.
The resulting sequence is (2,1,1). In this sequence, 1 occurs twice, and 2 occurs once.
Sample Input 2
10 1 2 1 3 2 4 2 5 8 1
Sample Output 2
10 7 0 4 0 3 0 2 3 0
按字典序排列,很容易想到贪心。将石堆按大小排列,每次拿出当前最大值,会发现有两种情况:
第一种情况
当次大值3的最左侧(记为y)的一个在最大值5最左侧(记为x)一个的左边时,会发现当把所有的5消成3时最优的情况x位总是最大的,所以x位的答案就为该值个数×(最大值-最小值),操作完后接下来的最大值就变成了j
第二种情况
当次大值3的最左侧(记为y)的一个在最大值5最左侧(记为x)一个的右边时,x位的答案与上面的情况相同,但操作完后的最大值任为x
在实际编写时,我们可以先将数组排序,从大到小操作,对于每个最大值记为f,找到其次大值t求出f位的答案。
- 如果为情况一,让f=t循环下去。
- 如果为情况二,f不变,让f(最大值)位的值变成次大值,方便接下去处理
最后,一定要记得开long long,就因为这个挂了好几次
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,t=2,f=1; 4 long long ans[100005]; 5 struct N{int data,num;}a[100005]; 6 bool comp(N x,N y){if(x.data==y.data) return x.num<y.num;else return x.data>y.data;} 7 int main(){ 8 scanf("%d",&n); 9 for(int i=1;i<=n;++i) scanf("%d",&a[i].data),a[i].num=i; 10 sort(a+1,a+n+1,comp); 11 while(t<=n){ 12 while(a[t].data==a[t-1].data) t++; 13 ans[a[f].num]+=1ll*(a[f].data-a[t].data)*(t-1); 14 if(a[t].num>a[f].num) a[f].data=a[t].data; 15 else f=t; 16 t++; 17 } 18 ans[a[f].num]+=1ll*a[f].data*n; 19 for(int i=1;i<=n;++i) printf("%lld\n",ans[i]); 20 }
以上是关于Atcoder 2335 Frequency 题解的主要内容,如果未能解决你的问题,请参考以下文章
Atcoder Beginner Contest 251 D——题解
AtCoder Beginner Contest 115 题解