Codeforces Round #519 by Botan Investments E. Train Hard, Win Easy(思维+贪心)

版权声明:若转载请附上原博客链接,谢谢! https://blog.csdn.net/Link_Ray/article/details/83550209

题目链接

题意

每个人都可以解决A题和B题,得分分别是 x i x_i y i y_i ,他可以任意和他不讨厌的人组队,一个队伍中每个人都只能做 A A B B 中的一道题,且每道题都只能由一个人来完成,队伍中两道题得分的总和越少越好。求出每个人所参与的所有队伍的得分总和。

题解

现在有c和d两个人组队,他们对于A题和B题的得分分别是, x c , y c x_c,y_c x d , y d x_d,y_d 。c可以做A题的条件是 x c + y d x d + y c x_c+y_d \leq x_d+y_c 。移项一下变成 y d x d y c x c y_d-x_d \leq y_c-x_c 。 所以我们可以按照每个人 y x y-x 进行排序,假设现在计算第i个人的得分,那么如果他和前 i 1 i-1 个人组队的话,他一直做的都是A题和后 n i + 1 n-i+1 个人组队的话做的都是B题。再分别求 x x y y 的前缀和就可以做到 O ( 1 ) O(1) 计算一个人的得分。最后再根据讨厌的关系减一减就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5+5;

struct node {
    ll x,y;
    int id;
    ll val;
    bool operator <(const node& rhs) const {
        return val < rhs.val;
    }
}a[maxn], b[maxn];

ll prex[maxn], prey[maxn];
ll ans[maxn];
int n,m;
ll get(ll x, ll _x, ll _y, int pos) {
    ll px = pos;
    // cout << px <<" ";
    ll ret = 0;
    ret += prey[px]+_x*px;
    // cout << ret <<" ";
    ret += prex[n]-prex[px]+_y*(n-px);
    // cout << ret <<" ";
    ret -= (_x+_y);
    // cout << ret <<endl;
    
    return ret;
}
int main() {
    
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) {
        scanf("%lld%lld", &a[i].x, &a[i].y);
        a[i].val = a[i].y-a[i].x;
        b[i].x = a[i].x; b[i].y = a[i].y;
        a[i].id = i;
    }
    sort(a+1,a+n+1);
    // cout << a[4].val << endl;
    for(int i = 1; i <= n; ++i) {
        prex[i] = prex[i-1]+a[i].x;
        prey[i] = prey[i-1]+a[i].y;
    }
    for(int i = 1; i <= n; ++i) {
        // cout <<i <<" ";
        ans[a[i].id] = get(a[i].y-a[i].x, a[i].x, a[i].y, i);
        // cout << endl;
    }
    for(int i = 0; i < m; ++i) {
        ll u,v;
        scanf("%lld%lld", &u, &v);
        ll ret = min(b[u].x+b[v].y, b[u].y+b[v].x);
        // cout << ret << endl;
        ans[u] -= ret;
        ans[v] -= ret;
    }
    for(int i = 1; i <= n; ++i)
        cout << ans[i] <<" ";
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Link_Ray/article/details/83550209