Changement de salaire

Lien

https://codeforces.com/contest/1251/problem/D

Le titre

Vous êtes à la tête d'une grande entreprise. n personnes travaillent chez vous, et n est impair (c'est-à-dire que n n'est pas divisible par 2).

Vous devez distribuer les salaires à vos employés. Au départ, vous avez des dollars pour cela, et le i-ème employé devrait recevoir un salaire de li à ri dollars. Vous devez répartir les salaires de manière à ce que le salaire médian soit maximum possible.

Pour trouver la médiane d'une séquence de longueur impaire, vous devez la trier et placer l'élément en position médiane après le tri. Par exemple:

la médiane de la séquence [5,1,10,17,6] est 6,
la médiane de la séquence [1,2,1] est 1.
Il est garanti que vous avez suffisamment d'argent pour payer le salaire minimum, c'est-à-dire \ (l_1 + l_2 + ⋯ + l_n≤s. \)

Notez que vous n'avez pas à dépenser tous vos dollars en salaires.

Vous devez répondre à des cas de test.

Entrée
La première ligne contient un entier t \ ((1≤t≤2⋅10 ^ 5) \) - le nombre de cas de test.

La première ligne de chaque requête contient deux entiers n et s ( \ (1≤n <2⋅10 ^ 5,1≤s≤2⋅10 ^ {14} \) ) - le nombre d'employés et le montant d'argent que vous avoir. La valeur n n'est pas divisible par 2.

Les n lignes suivantes de chaque requête contiennent les informations sur les employés. La i-ème ligne contient deux entiers li et ri \ ((1≤li≤ri≤10 ^ 9) \) .

Il est garanti que la somme de tous les n sur toutes les requêtes ne dépasse pas \ (2⋅10 ^ 5 \) .

Il est également garanti que vous avez suffisamment d'argent pour payer le salaire minimum à chaque employé, c'est-à-dire \ (\ sum_ {i = 1} ^ nl_i≤s \)

Sortie
Pour chaque scénario de test, imprimez un entier - le salaire médian maximum que vous pouvez obtenir.

Exemple d'
entrée

3
3 26
10 12
1 4
10 11
1 1337
1 1000000000
5 26
4 4
2 4
6 8
5 6
2 7

outputCopy

11
1337
6

Remarque
Dans le premier cas de test, vous pouvez répartir les salaires comme suit: sal1 = 12, sal2 = 2, sal3 = 11 (sali est le salaire du i-ème employé). Le salaire médian est alors de 11.

Dans le deuxième cas de test, vous devez payer 1337 dollars au seul employé.

Dans le troisième cas de test, vous pouvez répartir les salaires comme suit: \ (sal_1 = 4, sal_2 = 3, sal_3 = 6, sal_4 = 6, sal_5 = 7. \) Le salaire médian est alors 6.

Des idées

Médiane d'énumération binaire \ (k \) , traverser tous les employés une fois, pour les personnes avec \ (r_i \) inférieur à \ (k \) , émettre \ (l_i \) yuan, \ (cntl ++ \) , pour \ (l_i \ ) Les personnes supérieures à k donnent \ (l_i \) yuan, \ (cntr ++ \) , puis prennent \ (n / 2-cntl \) parmi les personnes restantes et donnent \ (l_i \) pour que leur salaire soit inférieur à \ ( k \) , et enfin les personnes restantes donnent \ (k \) . Et pour juger si le nombre de personnes supérieur et inférieur à \ (k \) est légal et le montant total de l'argent émis ne peut pas être supérieur à \ (S \) .
Cette question est à noter que la plage est alors divisée en deux, ne pas avoir une monotones entre l' infini et l' infini positif, tel que l' échantillon 1, \ (K \) prend \ (1 \) n'est pas illégal, mais la réponse peut être \ ( 6 \) . On peut trouver que la réponse est monotone de \ (a [n / 2 + 1] .l \) à l'infini positif (ou en \ (a [n / 2 + 1] .l \)\ ( l \)Tri du premier mot-clé) à \ (a [n / 2 + 1] .r \) (le tri avec \ (r \) comme premier mot-clé) est monotone). \ (k = a [n / 2 + 1] .l \) , il peut y avoir \ (n / 2 \) individus inférieurs ou égaux à \ (k \) , \ (n / 2 \) individus supérieurs à \ (k \) .

Code

#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
const int N=200010;
typedef pair<LL,LL> PII;
PII a[N];
int n;
LL s,tmp[N];
vector<LL> v;
bool check(LL k){
    int ls=0,rs=0,cnt=0;
    LL sum=0;
    for(int i=1;i<=n;++i){
        if(a[i].y<k) ls++,sum+=a[i].x;
        else if(a[i].x>k) rs++,sum+=a[i].x;
        else tmp[++cnt]=a[i].x;
    }
    if(sum>s||ls>n/2||rs>n/2) return false;
    for(int i=1;i<=cnt;++i) {
        if(ls==n/2) break;
        sum+=tmp[i];
        ls++;
    }
    sum+=(n/2+1-rs)*k;
    return sum<=s;
}
signed main(){
    int T;
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld",&n,&s);
        for(int i=1;i<=n;++i)
            scanf("%lld%lld",&a[i].x,&a[i].y);
        sort(a+1,a+1+n);
        LL l=a[n/2+1].x,r=1e14,ans;
        while(l<=r){
            LL mid=(l+r)/2;
            if(check(mid)){
                l=mid+1;
                ans=mid;
            }
            else r=mid-1;
        }
        cout<<ans<<endl;
    }

    return 0;
}

Je suppose que tu aimes

Origine www.cnblogs.com/jjl0229/p/12760049.html
conseillé
Classement