1. 程式人生 > >枚舉 + 三分

枚舉 + 三分

scrip distinct rip wid main printf ati lin -i

Define the simple skewness of a collection of numbers to be the collection‘s mean minus its median. You are given a list of n (not necessarily distinct) integers. Find the non-empty subset (with repetition) with the maximum simple skewness.

The mean of a collection is the average of its elements. The median of a collection is its middle element when all of its elements are sorted, or the average of its two middle elements if it has even size.

Input

The first line of the input contains a single integer n (1?≤?n?≤?200 000) — the number of elements in the list.

The second line contains n integers xi (0?≤?xi?≤?1?000?000) — the ith element of the list.

Output

In the first line, print a single integer k — the size of the subset.

In the second line, print k

integers — the elements of the subset in any order.

If there are multiple optimal subsets, print any.

Example Input
4
1 2 3 12
Output
3
1 2 12
Input
4
1 1 2 2
Output
3
1 1 2
Input
2
1 2
Output
2
1 2
Note

In the first case, the optimal subset is 技術分享圖片, which has mean 5, median 2, and simple skewness of 5?-?2?=?3.

In the second case, the optimal subset is 技術分享圖片. Note that repetition is allowed.

In the last case, any subset has the same median and mean, so all have simple skewness of 0.

題目分析 : mean 平均值 從 n 個數中選出任意個,讓其平均值減去中位數答案最大,首先答案一定是奇數個,反證法,若你是偶數個數,當你去掉正中間稍大的那個後,所求答案一定是大於之前的情況的,那麽根據這個條件我們就可以枚舉中位數,然後再三分長度即可

代碼示例 :

#define ll long long
const ll maxn = 2e5+5;
const double pi = acos(-1.0);
const ll inf = 0x3f3f3f3f;

ll n;
ll pre[maxn], sum[maxn];
ll pos = 1, len = 0;
double ans = 0;

double fun(ll lenn, ll x){
    ll s = 0;
    s += sum[x] - sum[x-lenn-1];
    s += sum[n] - sum[n-lenn];
    double mean = 1.0*s/(1+lenn*2);
    return mean-1.0*pre[x];
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    for(ll i = 1; i <= n; i++){
        scanf("%lld", &pre[i]); 
    }
    sort(pre+1, pre+1+n);
    for(ll i = 1; i <= n; i++) sum[i] = sum[i-1] + pre[i];
    for(ll i = 2; i < n; i++){
        ll l = 1, r = min(i-1, n-i);
        for(ll j = 1; j <= 50; j++) {  
            ll lm = l + (r - l)/3;
            ll rm = r - (r - l)/3;
            double lf = fun(lm, i);
            double rf = fun(rm, i);
            
            if (lf > rf) r = rm;
            else l = lm;
            if (lf > ans) {pos = i; len = lm; ans = lf;}
            if (rf > ans) {pos = i; len = rm; ans = rf;}
        }
    }
    printf("%lld\n", len*2+1);
    for(ll i = pos-len; i <= pos; i++){
        printf("%lld ", pre[i]);
    }   
    for(ll i = n-len+1; i <= n; i++){
        printf("%lld%c", pre[i], i==n?‘\n‘:‘ ‘);
    }
    return 0;
}

枚舉 + 三分