您的位置:首页 > 产品设计 > UI/UE

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

2015-10-05 19:01 351 查看
问题描述
给出一个整数序列, 去除序列中连续相邻的重复元素(只保留一个), 剩下来的数的和称之为序列的beauty.

现在给你一个长度为nn的整数序列AA.  问序列AA的所有子序列的beauty的和是多少. 由于答案可能很大, 你只要输出答案对10^9+710​9​​+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(1≤n≤10​5​​), 表示序列的大小. 接下来一行包含nn个整数a_1,a_2,...,a_na​1​​,a​2​​,...,a​n​​, 表示序列AA, (1 \le a_i \le 10^9)(1≤a​i​​≤10​9​​).


输出描述
对于每组数据, 输出答案对10^9+710​9​​+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}2​n−i​​种.
考虑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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: