codechef-Set Difference

Set Difference

                            Time Limit: 1 sec       Source Limit:   50000 Bytes

Churu is working as a data scientist in Coderpur. He works on a lot of data on the daily basis. One day, he found an interesting problem, which was very easy to solve for small data but was getting more complex with increasing number of data points. So, Churu needs your help in solving this problem.
Given a set S of N non-negative integers (Some integers might occur more than once in the set), find out the value of SETDIFF(S).
这里写图片描述
Where max(s) represents the maximum value in set s whereas min(s) represents the minimum value in the set s.
As value of SETDIFF(S) can be very large, print it modulo (109 + 7) .
There might be repeated values in the set. For set S = {1,2,2}, consider that first 2 is not same as the second 2 and there will be two different subsets {1,2}. See last sample case for the more clarifications.

Input

First line of input contains an integer T denoting number of test cases.
For each test case, first line will contain an integer N denoting number of elements in set S.
Next line contains N space separated integers denoting the set S.

Output

For each test case, print a single integer representing the answer of that test case.

Note

Two subsets will be called different if there exists an index i such that S[i] occurs in one of the subset and not in another.
Constraints

Subtask #1: 20 points
1 ≤ T ≤ 5, 1 ≤ N ≤ 1000, 0 ≤ value in set ≤ 109
Subtask #2: 25 points
1 ≤ T ≤ 5, 1 ≤ N ≤ 105, 0 ≤ value in set ≤ 1000
Subtask #3: 55 points
1 ≤ T ≤ 5, 1 ≤ N ≤ 105, 0 ≤ value in set ≤ 109
Example

Input:
4
2
1 2
3
1 2 3
4
1 2 3 4
3
1 2 2

Output:
1
6
23
3

Explanation

For first case answer will be 2-1 = 1.
For the second case:

Subset = {1}, max(s)-min(s) = 0.
Subset = {2}, max(s)-min(s) = 0.
Subset = {3}, max(s)-min(s) = 0.
Subset = {1,2}, max(s)-min(s) = 1.
Subset = {2,3}, max(s)-min(s) = 1.
Subset = {1,3}, max(s)-min(s) = 2.
Subset = {1,2,3}, max(s)-min(s) = 2.
So the output will be 1+1+2+2 = 6.
In the last case, there are three subsets, {1,2}, {1,2} and {1,2,2} having max(s) - min(s) = 1 for each.

题目大意:给定一个含N个非负整数的集合S(集合中元素可重复),求SETDIFF(S)的值。
需要注意的是两个子集当存在至少一个下标i,是的S[i]在其中一个子集中,而不在另一个子集中,另外取余也需要注意

题目思路:找规律。

题目链接:Set Difference

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#define MOD 1000000007
using namespace std;
long long pownum[100100];
int n;
int num[100100]; 
void solve()
{
    pownum[0] = 1;
    for (int i = 1; i <=100000; i++)
    {
        pownum[i] = (pownum[i - 1] * 2) % MOD;
    }
}

int main(){
    int t;
    cin >> t;
    solve();
    while(t--)
    {
        cin >> n;
        for (int i = 0; i < n; i++)
        {
            cin >> num[i];
        }
        sort(num,num + n);
        long long sum1 = 0,sum2 = 0;
        //这是未优化前的代码,还需要排列组合函数。外面i的循环代表从S中取几个数,可以发现随着i的变化num[j] * C(n - j - 1, i + 1)中只有i + 1在变化,于是可以想到二项式定理,去掉外面那层循环。

        /*for (int i = 0; i <= n - 2; i++) { for (int j = 0; j < n; j++) { if (n - j - 1 > 0) { sum1 += num[j] * C(n - j - 1, i + 1); } if (j > 0) { sum2 += num[j] * C(j,i + 1); } } }*/
        //优化过后
        for (int j = 0; j < n; j++)
        {
                sum1 =(sum1+ num[j] * pownum[n-j-1] )% MOD;
                sum2 =( num[j] * pownum[j] +sum2)% MOD;
        }
        cout << ((MOD+sum2 - sum1) % MOD) << endl;
    }
    return 0;
}

你可能感兴趣的:(找规律)