显然,我们可以发现一个序列是“好的”当且仅当这个序列中的最大值等于这个序列中的其他数之和相加,所以我们只需要保证序列单调递减,同时维护一下这个序列里面元素之和我们就可以O(1)判断一个序列是不是“好的”序列(a1=Sum−a1)
由于题目要求求出去掉哪些元素之后,这个序列会变为一个“好的”序列,所以我们只需要把原序列排序之后再按照刚刚说过的办法O(1)判断,只需要吧把原序列之中的Sum减去我们需要去掉的元素即可
还有一点需要注意,我们需要特判去掉第一个的情况,这样删去后最大值就是原先的次大数,即a2
上代码QwQ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
#include<bits/stdc++.h>
#define INF 2147483647 #define ll long long
int Inp(){ char c = getchar(); int Neg = 1; while(c < '0' || c > '9'){ if(c == '-') Neg = -1; c = getchar(); } int Sum = 0; while(c >= '0' && c <= '9'){ Sum = ((Sum << 3) + (Sum << 1)) + c - '0'; c = getchar(); } return Neg * Sum; }
struct Node{ ll x; int k; }s[200010];
bool Cmp(Node a, Node b){ return a.x > b.x; }
int Ans[200010];
int main(){ int n = Inp(); ll Sum = 0; for(int i = 1; i <= n; i++){ s[i].x = Inp(); Sum += s[i].x; s[i].k = i; } std::sort(s + 1, s + n + 1, Cmp); int Cnt = 0; if(Sum - s[1].x - s[2].x == s[2].x) Ans[++Cnt] = s[1].k; for(int i = 2; i <= n; i++){ if(Sum - s[1].x - s[i].x == s[1].x) Ans[++Cnt] = s[i].k; } printf("%d\n", Cnt); for(int i = 1; i <= Cnt; i++) printf("%d ", Ans[i]); }
|