zoukankan      html  css  js  c++  java
  • CF1043E Solution

    题目链接

    题解

    可以发现枚举两个在一组里的数会TLE,加之只有两个参数限制与数据范围,容易想到排序算法。

    计算第(i)个人的分数和需要知道他在每一组里是(x)还是(y),因此排序需要满足(a_i)前的数与(a_i)组合时为(x)更优,而(a_i)后的数与(a_i)组合时为(y)更优(反之亦可),也就是(x_i+y_{i+1}<x_{i+1}+y_i)

    而对于(a_i),则分数和:

    [=sumlimits_{j=1}^{i-1} (x_j+y_i)+sumlimits_{j=i+1}^n(x_i+y_j)\ =sumlimits_{j=1}^{i-1} x_j+y_icdot (i-1)+sumlimits_{j=i+1}^ny_j+x_icdot (i-1) ]

    两个(Sigma)用前缀和维护即可。

    此外,对于不可以组队的两个数,记录它们组队时的分数,在统计答案时分别减去即可。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=3e5+10;
    struct node{int x,y,id;} a[N];
    bool cmp(node a,node b) {return a.x+b.y<a.y+b.x;} 
    int id[N],mi[N],sumx[N],sumy[N];
    //id[i]:排序前下标为i的元素排序后的下标,mi[i]:a[i]因不可在一起组队需减去的分数
    signed main()
    {
    	int n,m,u,v;
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++) {scanf("%lld%lld",&a[i].x,&a[i].y); a[i].id=i;}
        //排序
    	sort(a+1,a+n+1,cmp);
        //处理前缀和与id数组
    	for(int i=1;i<=n;i++) sumx[i]=sumx[i-1]+a[i].x,sumy[i]=sumy[i-1]+a[i].y;
    	for(int i=1;i<=n;i++) id[a[i].id]=i;
        //处理不可在一起组队的元素
    	while(m--)
    	{
    		scanf("%lld%lld",&u,&v);
    		if(id[u]<id[v]) mi[u]+=a[id[u]].x+a[id[v]].y,mi[v]+=a[id[u]].x+a[id[v]].y;
    		else mi[u]+=a[id[u]].y+a[id[v]].x,mi[v]+=a[id[u]].y+a[id[v]].x;
    	}
        //统计答案
    	for(int i=1;i<=n;i++)
    	{
    		int t=id[i];
    		printf("%lld ",sumx[t-1]+a[t].y*(t-1)+sumy[n]-sumy[t]+a[t].x*(n-t)-mi[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Petapoco 数据库操作类
    .net Cookie操作公共方法 CookieHelper
    .net 服务端缓存 Cache/CacheHelper
    Base64加密解密方法
    对多字段进行去重 ( Linq 方式 )
    BootStrap之 提示工具(Tooltip)插件
    bootstrap之弹出框
    Jquery 强大的表单验证操作
    强大的数据库工具 dbForge Studio ForMySql
    My操作小技巧
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14257469.html
Copyright © 2011-2022 走看看