Set Difference(所有子集的最值差)

点击打开题目链接https://www.codechef.com/problems/SETDIFF

Set Difference

Problem code: SETDIFF

All submissions for this problem are available.

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.


求所有子集的 最大值减去最小值 的和  ,先对全集排个序,它的子集个数为2^n;其中,以{1,2,3,3

,5}为例,最大值是5,以5为最大值的子集个数为C(4,0)+C(4,1)+C(4,2)+C(4,3)+C(4,4),根据杨辉三角

的性质,C(n,0)+C(n,1)+.......+C(n,n)=2^n;所以C(4,0)+C(4,1)+C(4,2)+C(4,3)+C(4,4)=2^4;

以与5相邻的那个3为最大值的子集个数为C(3,0)+....C(3,3);。。。。以此类推;算出最大值的和

最小值同理;求出最大值的和与最小值的和,做个差就是答案;(别忘了那个+mod,具体看代码)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#define maxn 100010

using namespace std;

const int mod=1e9+7;
typedef unsigned long long ull;

ull p[maxn];
int arr[maxn];
int main()
{
    int i;
    p[0]=1;
    for(i=1;i<maxn;++i)
    {
        p[i]=(p[i-1]*2)%mod;
    }
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(i=0;i<n;++i)
        {
            scanf("%d",&arr[i]);
        }
        sort(arr,arr+n);
        ull mmax=0;
        for(i=n-1;i>=0;--i)
        {
            mmax=(mmax+(arr[i]*p[i])%mod)%mod;
        }
        ull mmin=0;
//        for(i=0;i<n;++i)这样也行
//        {
//            mmax=(mmax-(arr[i]*p[n-i-1])%mod+mod)%mod;
//        }
        for(i=0;i<n;++i)
        {
            mmin=(mmin+(arr[i]*p[n-i-1])%mod)%mod;
        }
        ull ans=(mmax-mmin+mod)%mod;
        //必须+mod,因为mmax、mmin都是对mod取余后的结果,谁大谁小不一定,而ans一定大于0
        printf("%llu\n",ans);
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 04:27:47

Set Difference(所有子集的最值差)的相关文章

python 数据类型 --- 集合

1. 注意列表和集合的区别 set 列表表现形式: list_1 = [1,3,4];  集合表现形式:set_1= set() list_1 = [1,2,3,4,23,4,2] print(list_1,type(list_1)) list_1 = set(list_1) print(list_1,type(list_1)) list_2 = set([2,4,6,8,10]) print(list_2,type(list_2)) #运行结果 [1, 2, 3, 4, 23, 4, 2] <

python第三节

字符集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 常用操作 list_1 = [1,4,5,7,3,6,7,9] list_1 = set(list_1) list_2 =set([2,6,0,66,22,8,4]) # print(list_1,list_2) # # #交集 # print(list_1.intersection(list_2)) # #并集 # print(list_

python(三)

数据类型和文件 1.1 python字典 字典书写格式: #!/usr/bin/env python #key-value info = { 'stu1101': "zhangsan", 'stu1102': "lizi", 'stu1103': "wangwu", } 查询 print(info) print("select-->",info["stu1101"]) #names = info[&q

python之路,day3

十八.集合 无序,不重复的数据组合 1. 去重2. 关系测试 list_1 = [1, 4, 5, 7, 3, 6, 7, 9]list_1 = set(list_1)list_2 = set([2, 66, 0, 6, 22, 8, 4])list_3 = set([1, 5, 7])# 交集# set([4, 6])print list_1.intersection(list_2)# 并集# set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 66, 22])print l

学习Python基础--------3

集合操作 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重 关系测试,测试两组数据之前的交集,差集,并集等关系# Author:Zhiyu Su list_1 = [1,4,5,7,3,6,7,9] list_1 = set(list_1) #转换为集合 list_2 = set([2,6,0,66,22,8,4,]) print(list_1,list_2) ''' #交集 intersection print(list_1.intersection

python学习笔记(集合的使用、文件操作、字符编码与转码、函数)

集合 集合(set):把不同的元素组成一起形成集合,是python基本的数据类型. 集合元素(set elements):组成集合的成员 为什么需要集合? 集合的作用 1 .列表去重复数据 按照现有知识的解决思路:先设置空列表,然后使用for寻获,把需要去重的列表的第一个数据放到新列表中,然后依次取出第二个数据,把第二个数据和第一个数据作比较,如果不一样,则存入新列表中:以此类推,每取一次都要和新列表中的数据作对比,不一样的则添加入新列表中. 2. 关系测试 比如有学员同时报了python班和l

集合-列表的关系测试

# -*- coding: utf-8 -*-#集合是无序的 list_1=[1,4,7,3,6,7]list_3=set([1,3,7])list_4=[377,88]#集合去重list_1=set(list_1)list_2=[1,33,4,7,66,5,8]#交集,取出两个列表中相同的数据list_x=list_1.intersection(list_2)#并集,合并列表并去重list_n=list_1.union(list_2)#差集,list1中有,list2中没有的数据print(l

python 集合实例列举

#集合是无序的list_1 = [1,3,4,5,7,3,6,7,9]list_1 = set(list_1) #集合去重 list_2 = set([2,6,0,66,22,8,4])#交集print(list_1.intersection(list_2)) #并集print(list_1.union(list_2))#差集:保留1有 2无的print(list_1.difference(list_2))#子集:3是1的子集list_3 = set([1,3,7])print(list_3.i

python学习7

1.在列表和字典的循环中,不能直接删除它们 删除第1.3位的元素 lis = [11,22,33,44,55] #方法1 '''lis = [11,22,33,44,55] li = [] for i in range(len(lis)): if i % 2 == 0: li.append(lis[i]) lis = li print(li) ''' #方法2 lis = [11,22,33,44,55] tu = tuple(lis) for i in range(len(lis)): if