前缀和+排序——cf1043E

先不考虑第二个条件

要求i和所有其他人的分数和最小,选择x还是y,可以推出一个公式,即差xi-yi小的j都选y,反之都选x

那么按照xi-yi排序即可

然后再考虑第二个条件,做减法就行

/*
xi+yj<xj+yi
xi-yi<xj-yj
xi-yi值小取xi
xi-yi值大取yi 
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define N 300005
struct Node {
    ll x,y,id;
}p[N],q[N];
int n,m;
ll ans[N],sumx[N],sumy[N];
int cmp(Node a,Node b){return a.x-a.y<b.x-b.y;}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
    for(int i=1;i<=n;i++)q[i]=p[i];
        
    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++){
        sumx[i]=sumx[i-1]+p[i].x;
        sumy[i]=sumy[i-1]+p[i].y;
    }
    for(int i=1;i<=n;i++){
        ans[p[i].id]+=(i-1)*p[i].y;
        ans[p[i].id]+=sumx[i-1];
        ans[p[i].id]+=(n-i)*p[i].x;
        ans[p[i].id]+=sumy[n]-sumy[i];
    }
    
    while(m--){
        int u,v;
        scanf("%d%d",&u,&v);
        Node a=q[u],b=q[v];
        ll sum=min(a.x+b.y,a.y+b.x);
        ans[u]-=sum;
        ans[v]-=sum;
    }
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<" ";
}
原文地址:https://www.cnblogs.com/zsben991126/p/11441649.html