支援城市

题源:https://cometoj.com/contest/58/problem/B?problem_id=2757

题目描述

1267年,战争的味道在空气中弥漫,强大的尼弗迦德帝国蓄势待发。觊觎着雅鲁加河对岸的北方领域。莱里亚的女王米薇为了抵御尼弗迦德帝国的进攻,在莱里亚王国内建造了 nn 个城市。第 ii 个城市中居住着 w_iwi​ 个公民。当尼弗迦德帝国进攻某一个城市时,其他所有城市将支援被进攻的城市。但这些城市的居民会因为支援其他城市而产生不满意度。

当城市 aa 要前往城市 bb 支援时,会产生 (w_a-w_b)^2(wa​−wb​)2 点不满意度。

米薇女王想知道对于每个城市被进攻时,分别会产生多少点不满意度。

即对于每个城市 xx ,你需要回答 \sum_{i=1}^n{(w_i-w_x)^2}∑i=1n​(wi​−wx​)2 的值。

输入描述

 

第 11 行一个整数 nn ,代表有 nn 座城市。

第 22 行 nn 个整数,第 ii 个整数 w_iwi​ 代表第 ii 个城市的人口数量。

  • 2 \leq n \leq 10^52≤n≤105
  • 1 \leq w_i \leq 10^61≤wi​≤106。

输出描述

 

一行 nn 个整数,分别是第 11 个被攻击产生的不满意度到第 nn 个城市被攻击的不满意度。

样例输入 1 

3
3 3 3

样例输出 1

0 0 0 

样例输入 2 

3
3 4 5

样例输出 2

5 2 5 

样例输入 3 

5
19 4326 7891 744 999

样例输出 3

82004658 55159127 173256882 64500983 59594018 

题解:

解题思路:

朴素算法是双重循环按照题意求每一个结果(Wa-Wb)^2会超时。

仔细思考发现(Wa-Wb)^2=Wa^2+Wb^2-2*Wa*Wb,可以进行公式转换。于是这就能想法转成一个循环来做了。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
typedef long long ll;

int  a[N];

int main()
{
//	freopen("input.txt", "r", stdin);
	//提交时注释,调试时取消注释!!! 
	int n;
	cin>>n; 
	ll sum1=0;//统计所有城市公民之和
	ll sum2=0;//统计所有城市公民a[i]^2之和 
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		sum1+=a[i];
		sum2+=a[i]*a[i]; 
	}
	for(int i=0;i<n;i++)
	{
		ll res=(n-1)*a[i]*a[i]+(sum2-a[i]*a[i])-2*a[i]*(sum1-a[i]);
		printf("%lld ",res);
	}
	cout<<endl;
	return 0;
}

提交的时候发现,我把a[N]的类型改成int就错了。原因是a[i]*a[i]爆int了。a[i]和a[i]相乘不会将int自动转换成long long类型。

自动类型转换只限于在表达式所具有的类型之内转换。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值