【Codeforces Round #519 by Botan Investments E】Train Hard, Win Easy

【链接】 我是链接,点我呀:)
【题意】

【题解】


设每个人做第一题、第二题的分数分别为x,y
我们先假设没有仇视关系。
即每两个人都能进行一次训练。
那么
对于第i个人。
考虑第j个人对它的贡献
如果xi+yj<yi+xj
即xi-yi<xj-yj
也就是说,如果我们以x-y作为关键字升序排序的话。
那么在第i个人右边的所有人。他的xj-yj的值都大于xi-yi
那么这n-i个人对第i个人的贡献就都是xi+yj
可以用一个前缀和,轻松搞定区间的x,y和。
xi+yj>yi+xj的话。
情况类似。

最后对于有仇敌关系的(i,j)的话。
第i个人和第j个人的贡献都减去min(xi+yj,yi+xj)即可。

【代码】

#include <bits/stdc++.h>
#define ll long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
using namespace std;

const int N = 3e5;

struct abc{
    int x,y,id;
    bool operator < (const abc &b) {
        return (x-y)<(b.x-b.y);
    }
};

int n,m;
ll ans[N+10];
ll prex[N+10],prey[N+10];
abc a[N+10],b[N+10];

int main(){
    #ifdef ccy
            freopen("rush.txt","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    rep1(i,1,n) {
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id = i;
    }
    rep1(i,1,n) b[i] = a[i];
    sort(a+1,a+1+n);     

    rep1(i,1,n){
        prex[i]+=prex[i-1];
        prey[i]+=prey[i-1];
        prex[i]+=a[i].x;
        prey[i]+=a[i].y;
    }
    //xi+yj<yi+xj
    //xi-yi<=xj-yj

    //xi+yj>yi+xj
    //xi-yi>xj-yj
    rep1(i,1,n){
        ans[a[i].id] += 1LL*(i-1)*a[i].y+prex[i-1]-prex[0];
        ans[a[i].id] += 1LL*(n-i)*a[i].x+prey[n]-prey[i];
    }
    rep1(i,1,m){
        int x,y;
        scanf("%d%d",&x,&y);
        ans[x]-=min(b[x].x+b[y].y,b[x].y+b[y].x);       
        ans[y]-=min(b[x].x+b[y].y,b[x].y+b[y].x);       
    }
    rep1(i,1,n){
        printf("%lld ",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AWCXV/p/9925115.html