hdu Beauty of Sequence (好题_集合问题)


问题描述
给出一个整数序列, 去除序列中连续相邻的重复元素(只保留一个), 剩下来的数的和称之为序列的beauty.

现在给你一个长度为nn的整数序列AA.  问序列AA的所有子序列的beauty的和是多少. 由于答案可能很大, 你只要输出答案对10^9+7109+7取模的结果.

Note: 在数学中,某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列。 例如\{1,3,2\}{1,3,2}\{1, 4, 3, 5, 2, 1\}{1,4,3,5,2,1}的一个子序列.
输入描述
输入有多组数据. 第一行包含一个整数TT表示测试数据的组数. 对于每组数据:

第一行有一个整数n (1 \le n \le 10^5)n(1n105), 表示序列的大小. 接下来一行包含nn个整数a_1,a_2,...,a_na1,a2,...,an, 表示序列AA, (1 \le a_i \le 10^9)(1ai109).
输出描述
对于每组数据, 输出答案对10^9+7109+7取模的结果.
输入样例
3
5
1 2 3 4 5
4
1 2 1 3
5
3 3 2 1 2
输出样例
240
54
144

考虑每个数字对最终答案的贡献. 对于每个数, 我们只算它出现在连续相同元素的第一个时的贡献, 这样会使计算简便很多. 假设这个数是 a[i]a[i] , 那么i后面的随便选有 2^{n-i}2ni 种. 考虑 a[i]a[i] 前面的数, 要么一个不选, 要么选择的最后一个数和 a[i]a[i] 不同, 然后就可以算出来了.

#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL Mod = 1e9 + 7;
const int maxn = 1e5 + 10;
LL a[maxn];
LL pow2[maxn];
map<LL, LL> M;
void init()
{
    pow2[0] = 1;
    for(int i = 1; i < maxn; i++)
        pow2[i] = pow2[i-1] * 2 % Mod;
}
int main()
{
    int T, n;
    scanf("%d", &T);
    init();
    while(T--)
    {
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
            scanf("%lld", &a[i]);
        M.clear();
        LL ans = 0;
        for(int i = 0; i < n; i++)
        {
            LL t = M[a[i]];
            LL l = (pow2[i] - t + Mod) % Mod;
            LL sum = l * pow2[n-i-1] % Mod * a[i] % Mod;
            ans = (ans + sum) % Mod;
            M[a[i]] = (t + pow2[i]) % Mod;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值