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;
    }
    
  • 相关阅读:
    uboot编译配置过程
    APUE-数据库函数库
    值得推荐的C/C++框架和库 (真的很强大)
    ubuntu12.04图形界面与命令行界面切换
    ubuntu14.04 升级gcc的方法
    4. H5+css3
    3,css 内容
    2. 浏览器兼容性问题
    1,http协议
    页面添加水印
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14257469.html
Copyright © 2011-2022 走看看