E. Power of Points

传送门

题意

给你 n n n个点,其整数坐标为 x 1 , … x n x_1,\dots x_n x1,xn,它们位于一条数线上。

对于某个整数 s s s,我们构造线段 [ s , x 1 s,x_1 s,x1], [ s , x 2 s,x_2 s,x2], … \dots , [ s , x n s,x_n s,xn]。请注意,如果是 [ x i , s x_i,s xi,s],那么线段看起来就像[ x i , s x_i,s xi,s]。线段 [ a , b a, b a,b]覆盖了所有整数点 a , a + 1 , a + 2 , … , b a, a+1, a+2, \dots, b a,a+1,a+2,,b

我们将点 p p p的幂定义为与坐标为 p p p的点相交的线段数,记为 f p f_p fp

您的任务是计算每个 s ∈ { x 1 , … , x n } s \in \{x_1,\dots,x_n\} s{x1,,xn} ∑ p = 1 1 0 9 f p \sum\limits_{p=1}^{10^9}f_p p=1109fp,即从 1 1 1 1 0 9 10^9 109的所有整数点的 f p f_p fp之和。

例如,如果初始坐标为 [ 1 , 2 , 5 , 7 , 1 ] [1,2,5,7,1] [1,2,5,7,1],我们选择 s = 5 s=5 s=5,那么线段将是 [ 1 , 5 ] [1,5] [1,5], [ 2 , 5 ] [2,5] [2,5], [ 5 , 5 ] [5,5] [5,5], [ 5 , 7 ] [5,7] [5,7], [ 1 , 5 ] [1,5] [1,5].这些点的幂将是 f 1 = 2 , f 2 = 3 , f 3 = 3 , f 4 = 3 , f 5 = 5 , f 6 = 1 , f 7 = 1 , f 8 = 0 , … , f 1 0 9 = 0 f_1=2, f_2=3, f_3=3, f_4=3, f_5=5, f_6=1, f_7=1, f_8=0, \dots, f_{10^9}=0 f1=2,f2=3,f3=3,f4=3,f5=5,f6=1,f7=1,f8=0,,f109=0.它们的和为 2 + 3 + 3 + 3 + 5 + 1 + 1 = 18 2+3+3+3+5+1+1=18 2+3+3+3+5+1+1=18

输入

第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1\le t\le 10^4 1t104)–测试用例数。

每个测试用例的第一行包含一个整数 n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2\cdot 10^5 1n2105)–点数。

第二行包含 n n n个整数 x 1 , x 2 … x n x_1,x_2 \dots x_n x1,x2xn ( 1 ≤ x i ≤ 1 0 9 1 \le x_i \le 10^9 1xi109)–点的坐标。

保证所有测试用例的 n n n值之和不超过 2 ⋅ 1 0 5 2\cdot 10^5 2105

输出

对于每个测试案例,输出 n n n个整数,其中第 i i i个整数等于第 s = x i s=x_i s=xi个整数的所有点的幂之和。

思路

说了这么多废话,其实求得就是数组每个元素和其他元素差的绝对值之和 + n +n +n

举个例子 对于数组 [ 1 , 2 , 5 , 7 , 1 1, 2, 5, 7, 1 1,2,5,7,1] , , , 输出为 [ 16 , 15 , 18 , 24 , 16 16, 15, 18, 24, 16 16,15,18,24,16]

16 = ∣ 1 − 1 ∣ + ∣ 1 − 2 ∣ + ∣ 1 − 5 ∣ + ∣ 1 − 7 ∣ + ∣ 1 − 1 ∣ + 5 16=|1-1|+|1-2|+|1-5|+|1-7|+|1-1|+5 16=∣11∣+∣12∣+∣15∣+∣17∣+∣11∣+5
15 = ∣ 2 − 1 ∣ + ∣ 2 − 2 ∣ + ∣ 2 − 5 ∣ + ∣ 2 − 7 ∣ + ∣ 2 − 1 ∣ + 5 15=|2-1|+|2-2|+|2-5|+|2-7|+|2-1|+5 15=∣21∣+∣22∣+∣25∣+∣27∣+∣21∣+5
18 = ∣ 5 − 1 ∣ + ∣ 5 − 2 ∣ + ∣ 5 − 5 ∣ + ∣ 5 − 7 ∣ + ∣ 5 − 1 ∣ + 5 18=|5-1|+|5-2|+|5-5|+|5-7|+|5-1|+5 18=∣51∣+∣52∣+∣55∣+∣57∣+∣51∣+5
24 = ∣ 7 − 1 ∣ + ∣ 7 − 2 ∣ + ∣ 7 − 5 ∣ + ∣ 7 − 7 ∣ + ∣ 7 − 1 ∣ + 5 24=|7-1|+|7-2|+|7-5|+|7-7|+|7-1|+5 24=∣71∣+∣72∣+∣75∣+∣77∣+∣71∣+5

接下来那么问题就变得很简单了,先排序后求前缀和即可。

举个例子
   原数组 a : 1 , 2 , 5 , 7 , 1 a :1, 2, 5, 7, 1 a:1,2,5,7,1
       数组 b : 1 , 1 , 2 , 5 , 7 b:1, 1, 2, 5, 7 b:1,1,2,5,7
数组 s u m : 1 , 2 , 4 , 9 , 16 sum:1, 2, 4, 9, 16 sum:1,2,4,9,16

b b b数组进行二分就可以得到它的位置 p o s pos pos,剩下的用前缀和知识就可以求出答案了。

完整代码

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define int long long
const int N = 1e6 + 10 , mod = 998244353, M = 2 * N;
typedef pair<int, int> PII;
typedef long long ll;
const int INF_MAX = 0x3f3f3f3f3f3f3f3f;
int a[N], b[N], sum[N];
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i], b[i] = a[i];
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i++)sum[i] = sum[i - 1] + a[i];
    vector<int>ans;
    for (int i = 1; i <= n; i++)
    {
        int pos = lower_bound(a + 1, a + 1 + n, b[i]) - a;
        //cout << pos << endl;
        int num1 = pos - 1;
        int num2 = n - pos;
        int t1 = abs(b[i] * num1 - sum[pos - 1]);
        int t2 = abs(sum[n] - sum[pos] - num2 * b[i]);
        //cout << t1 << " " << t2 << endl;
        ans.push_back(t1 + t2 + n);
    }
    for (auto i : ans)
        cout << i << " ";
    cout << '\n';
}
signed main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T = 1;
    cin >> T;
    while (T--)solve();
    return 0;
}
Python中的np.power()函数是用来计算一个数组或数字的乘方的。它接受两个参数,第一个参数是要进行乘方运算的数组或数字,第二个参数是乘方的指数。根据参数的不同类型,np.power()函数的行为也会有所不同。 - 当第一个参数是一个单个数字,第二个参数也是一个单个数字时,np.power()函数会计算第一个数字的第二个数字次方。例如,np.power(2, 3)的结果是8,表示计算2的3次方。 - 当第一个参数是一个列表,第二个参数是一个单个数字时,np.power()函数会对列表中的每个数字分别进行乘方运算,结果返回一个新的列表。例如,np.power([2,3,4], 3)的结果是[8, 27, 64],表示对列表中的每个数字分别计算3次方。 - 当第一个参数是一个单个数字,第二个参数是一个列表时,np.power()函数会将第一个数字分别与列表中的每个数字进行乘方运算,结果返回一个新的列表。例如,np.power(2, [2,3,4])的结果是[4, 8, 16],表示将2分别计算2次方、3次方和4次方。 - 当第一个参数和第二个参数都是列表时,np.power()函数会将两个列表中对应位置的数字进行乘方运算,结果返回一个新的列表。例如,np.power([2,3], [3,4])的结果是[8, 81],表示分别计算2的3次方和3的4次方。 总结来说,np.power()函数可以对单个数字或列表中的数字进行乘方运算,并返回结果。具体返回结果的形式取决于输入参数的类型和形状。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值