题意: 首先定义集合的F值为  这个集合里面最大值和最小值的差。 现给出一个拥有n个数的集合(没有相同的元素), 要求求出这个集合内所有子集的F的值的和。例如: {4、7}这个集合里面有子集{4}、{7}、{4, 7}, 则这些子集的F值分别为4-4=0、7-7=0、7-4=3, 所以最后的结果就是0+0+3 = 3!

以下分析引用至 : http://blog.csdn.net/dragon60066/article/details/72599167

分析: 不难想到要先使数组升序方便计算和思考, 然后观察发现如果选定任意一头一尾两个元素, 假如为ai、aj (ai<aj) 那这个两个元素之间围起来的区间可以看成ai....aj这样的数集, 且这集合里面所有子集贡献的F值都等于 aj - ai, 那这个区域包含了多少个这样的F值的集合呢?用笔简单列出表后不难发现规律, 这个和为个(需要用到快速幂), 至于具体为什么, 可以看自己多加思考一下且在参考博客有说明。当时想到这个后马上打出了枚举程序

#include<bits/stdc++.h>
#define LL long long
using namespace std;
;
LL arr[];
LL mi[];
LL qmod(LL a, LL b, LL c)
{
    LL ans = ;
    while(b){
        ) ans = (ans*a)%c;
        a = (a*a)%c;
        b >>= ;
    }
    return ans;
}
int main(void)
{
    int n;
    scanf("%d", &n);
    ; i<n; i++){
        scanf("%lld", &arr[i]);
    }
    sort(arr, arr+n);
    LL sum = ;
    LL temp;
    ; i<n; i++){
        mi[i] = qmod(, i, mod);
    }
    ; i<n-; i++){
        ; j>i; j--){
            LL sub = arr[j] - arr[i];
            !=)temp = mi[j-i-];
            ;
            temp%=mod;
            sum += (((temp%mod)*(sub%mod))%mod)%mod;
            sum%=mod;
        }
    }
    printf("%lld\n", sum);
    ;
}

然后就可以顺利超时了, 因为像我这样做的复杂度是O(n^2)!需要优化!于是上网搜索看到了前缀和的解法, 甚是巧妙, 而且貌似榜上大佬大多也是这样做!

引用一下——>进一步思考,对于每个i, j,取值可能有,第一种前面系数是(a[2]-a[1]+a[3]-a[2]+...+a[n]-a[n-1])=a[n]-a[1],同理可以发现第二种是a[n]+a[n-1]-a[1]-a[2]......,那么就推出来了:

那这个直观一点的话到底是在干什么玩意呢?看下面根据描述打出来的表

看到规律了吧!发现系数是对称的, 那我们根据系数的规律枚举从0到n-2的2次方就行了!不过细想的话, 虽然是找到了系数的规律, 但是好像还是不好实现, 参考别人的程序看到别人使用了前后缀和的做法, 巧妙的完成了依据上面规律进行的枚举操作, 具体的话不好说, 看一下程序便知!

以下为拙略表达, 可以跳过: 不过我还是说一下, 按我的理解就是从前面到中间的系数(以n=6为例, 枚举从2^0到2^2的系数)倒是不难枚举出来, 但是后面的就略微麻烦了, 解决方法——>定义前后缀和(例:sumf[i]是从1到i的前缀和, sumb[i]是n-1到i的后缀和), 那还是以n=6为例, 2^0到2^2的系数分别可以用sumb[6] - sum[1] 、 sumb[5]-sumf[2]、 sumb[4]-sumf[3]来解决, 后面的2^3 可以 sumb[3] - sumf[4], 停!有没有发现 计算这个差的过程中实际就是 a6+a5+a4+a4-a4-a3-a1-a2! a3和a4巧妙的被约去了, 2^4的计算也是同样道理!类似于回文?好思想!

#include<bits/stdc++.h>
#define LL long long
using namespace std;
;
;
LL arr[maxn], sumf[maxn], sumb[maxn], mi[maxn];
LL quick_mod(LL a, LL b, LL c)
{
    LL ans = ;
    while(b){
        ) ans = (ans*a)%c;
        a = (a*a)%c;
        b >>= ;
    }
    return ans;
}
int main(void)
{
    int n;
    scanf("%d", &n);
    ; i<=n; i++)
        scanf("%d", &arr[i]);
    sort(arr+, arr++n);///使序列单调
    sumf[] = sumb[n+] = ;
    mi[] = ;
    ; i<n-; i++)
        mi[i] = quick_mod(, i, mod);///二的次方数组
    ; i<=n; i++)
        sumf[i] = sumf[i-] + arr[i];///前缀和
    ; i--)
        sumb[i] = sumb[i+] + arr[i];///后缀和
    LL ans = ;
    ; i<n; i++){ //实际就是0 -- n-2 次循环
        LL temp = (-sumf[i] + sumb[n-i+])%mod;
        ans = (ans%mod + (temp * mi[i-])%mod)%mod;
    }
    printf("%lld\n", ans);
    ;
}

#415 Div2 Problem C Do you want a data? (math && 前后缀和 && 快速幂)的更多相关文章

  1. #415 Div2 C

    #415 Div2 C 题意 给定一个数字集合,找到所有子集合最大值与最小值之差的和. 分析 列式子,找规律. $ (a_2 - a_1) * 2^0 + (a_3 - a_1) * 2^1 + .. ...

  2. HDU1757 A Simple Math Problem 矩阵快速幂

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  3. A Simple Math Problem(矩阵快速幂)(寒假闭关第一题,有点曲折啊)

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...

  4. hdu_3483A Very Simple Problem(C(m,n)+快速幂矩阵)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3483 A Very Simple Problem Time Limit: 4000/2000 MS ( ...

  5. HDU 1757 A Simple Math Problem (矩阵快速幂)

    题目 A Simple Math Problem 解析 矩阵快速幂模板题 构造矩阵 \[\begin{bmatrix}a_0&a_1&a_2&a_3&a_4&a ...

  6. HDU5950 Recursive sequence (矩阵快速幂加速递推) (2016ACM/ICPC亚洲赛区沈阳站 Problem C)

    题目链接:传送门 题目: Recursive sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total ...

  7. BestCoder Round #29——A--GTY's math problem(快速幂(对数法))、B--GTY's birthday gift(矩阵快速幂)

    GTY's math problem Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  8. CF954F Runner's Problem(动态规划,矩阵快速幂)

    CF954F Runner's Problem(动态规划,矩阵快速幂) 题面 CodeForces 翻译: 有一个\(3\times M\)的田野 一开始你在\((1,2)\)位置 如果你在\((i, ...

  9. BNU 4356 ——A Simple But Difficult Problem——————【快速幂、模运算】

    A Simple But Difficult Problem Time Limit: 5000ms Memory Limit: 65536KB 64-bit integer IO format: %l ...

随机推荐

  1. ~艾比郎~学Python之Python基础

    第一步: 尝试写Hello World程序 这是我用Python写出的第一个程序,我的一小步,我人生的一大步 在linux 下创建一个文件叫hello.py,如图所示 然后执行命令:python he ...

  2. SQL SERVER 字符串函数 STUFF()

    说明: STUFF 函数将字符串插入到另一个字符串中. 它从第一个字符串的开始位置删除指定长度的字符:然后将第二个字符串插入到第一个字符串的开始位置. 语法: STUFF ( character_ex ...

  3. 小菜鸟之Oracle数据库

    select * from STUDENT; select * from mark; select * from COURSE; select * from teacher; --注释 select ...

  4. idea 去除重复代码提醒

  5. js中onchange()的使用,实现功能,选择哪一张图片,显示哪一张

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. python内置函数简单归纳

    做python小项目的时候发现熟练运用python内置函数,可以节省很多的时间,在这里整理一下,便于以后学习或者工作的时候查看.函数的参数可以在pycharm中ctrl+p查看. 1.abs(x):返 ...

  7. QT多线程同步之QWaitcondition

    使用到多线程,无可避免的会遇到同步问题,qt提供几种同步线程的方法,在这里讲一下QWaitcondition的简单使用. 一.QWaitcondition,是通过一个线程达到某种条件来唤起另一个线程来 ...

  8. private修饰的方法可以通过反射访问,那么private的意义是什么?

    反射代码: package test; public class Person { private String userName= "Tom"; private void pla ...

  9. 关于的 let 关键字的一个小问题

    刚才在看阮一峰老师的<ES6标准入门>,在介绍 let 那一段时有这么一段话 我就自己在控制台试了一下这段代码,输出果然的是"abc",于是我就把代码稍微修改了下 也没 ...

  10. redis集群启动和关闭脚本

    创建startall.sh /usr/local/redis/bin/redis-server /usr/local/redis/redis-cluster/7001/redis.conf /usr/ ...