ICPC NEAU Programming Contest 2020~~ H. 排序

給你兩個長度均爲n的數列ai​和bi​,定義函數
在這裏插入圖片描述
你可以改變ai​內各元素的順序,使g(n)最小,求這個最小值。由於答案很大,請輸出答案對109+7取餘後的值

輸入描述

輸入的第一行爲一個整數T,代表測試用例的組數
接下來的T組測試用例按照如下格式給出:每組數據佔3行,第一行有2個整數n,表示數組長度,第二行有n個整數ai​,第三行有n個整數bi​

輸出描述

對於每組測試數據,在新的一行中輸出答案,由於答案很大,請輸出答案對109+7取餘後的結果

數據範圍
>1≤T≤10001≤T≤10001≤T≤10002≤n≤2⋅1052≤n≤2\cdot{10}^52≤n≤2⋅105∑n≤2⋅105\sum{n}≤2\cdot{10}^5∑n≤2⋅1051≤ai≤1061≤a_i≤10^61≤ai​≤1061≤bi≤1061≤b_i≤10^61≤bi​≤106
樣例輸入

1
2
7 17
77 77

樣例輸出

3696

樣例解釋
在這裏插入圖片描述
首先對g(x)進行分析,對於一個固定的i,f(l,i) 有 i 個,f(i,r)有n-i+1個,所以包含ai*bi 的f(l,r)有i * (n-i+1) 個。所以

for(int i = 1; i <= n; ++ i) {
	g(n) += i * (n - i + 1) * ai * bi;
}

而且b[n]是固定的,所以對a進行排序,採用貪心策略即可。代碼如下:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e6+1;
const int mod = 1e9+7;
long long a[maxn], b[maxn];

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i) {
            scanf("%lld", &a[i]);
        }
        for(int i = 1; i <= n; ++ i) {
            scanf("%lld", &b[i]);
        }
        for(int i = 1; i <= n; ++ i) {
            b[i] *= 1ll * i * (n-i+1);
        }
        sort(a+1, a+n+1, greater<int>());
        sort(b+1, b+n+1);
        long long sum = 0;
        for(int i = 1; i <= n; ++ i) {
            b[i] = b[i] % mod;
            sum = (sum + a[i] * b[i] % mod) % mod;
        }
        printf("%lld\n", sum % mod);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章