题目地址:C - Sigma Problem (atcoder.jp)https://atcoder.jp/contests/abc353/tasks/abc353_c
题意:给出n个正整数,使每两个不重复的数相加求和,若两数相加后大于,则取模再求和.
解题思路:首先看到题发现暴力是最简单的解决方法,但显然暴力会超时,因此可以使用双指针(相撞)进行优化
根据题意,每个数会与其他数进行一次发f(x,y)运算,即n-1次,算出总值.
题目与数字顺序无关,可先进行排序.
数字范围不超过10^8,因此有两种情况:
- 两数相加小于;
- 两数相加大于,但一定小于2*10^8.
所以要找到所有f(x,y)大于10^8的情况,用总值减去超过10^8的次数*10^8,使i,j同时进行变化降低时间复杂度,防止超时.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 100000000;
ll a[300010];
ll sum,cc;
int main()
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> a[i];
sum += (n-1)*a[i];
}
int j = n;
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
while(i<=j && a[i]+a[j]>=mod)
{
j--;
}
if(i<=j)
cc += n-j;
else
cc += n-i;
}
cout << sum-cc*mod <<endl;
}