前缀和+排序——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]<<" "; }