hdu 5496 Beauty of Sequence 枚举

Beauty of Sequence

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 195    Accepted Submission(s): 79


Problem Description
Sequence is beautiful and the beauty of an integer sequence is defined as follows: removes all but the first element from every consecutive group of equivalent elements of the sequence (i.e. unique function in C++ STL) and the summation of rest integers is the beauty of the sequence.

Now you are given a sequence  A  of  n  integers  {a1,a2,...,an} . You need find the summation of the beauty of all the sub-sequence of  A . As the answer may be very large, print it modulo  109+7 .

Note: In mathematics, a sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements. For example  {1,3,2}  is a sub-sequence of  {1,4,3,5,2,1} .
 

Input
There are multiple test cases. The first line of input contains an integer  T , indicating the number of test cases. For each test case:

The first line contains an integer  n   (1n105) , indicating the size of the sequence. The following line contains  n  integers  a1,a2,...,an , denoting the sequence (1ai109) .

The sum of values  n  for all the test cases does not exceed  2000000 .
 

Output
For each test case, print the answer modulo  109+7  in a single line.
 

Sample Input
  
  
3 5 1 2 3 4 5 4 1 2 1 3 5 3 3 2 1 2
 

Sample Output
  
  
240 54 144
 

Source
 


枚举第i个数能作为子序列中连续的数字的开头,那么 这个数字对总和的贡献为,下标从0开始

num[i] * 2^(n-i-1) * (2^i - 以和num[i]相等的数字作为结尾的方案数)

然后以num[i]结尾的方案数+= 2^i

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
using namespace std;

#define maxn 100007
int pow2[maxn];
int num[maxn];
#define mod 1000000007
#define ll long long
map<int,int>haha;
int main(){
    int t,n;
    scanf("%d",&t);
    pow2[0] = 1;
    for(int i = 1;i < maxn; i++)
        pow2[i] = pow2[i-1]*2%mod;
    while(t--){
        scanf("%d",&n);
        for(int i = 0;i < n; i++)
            scanf("%d",&num[i]);
        int sum1,ans = 0,sum=0,ha,he;
        haha.clear();
        for(int i = 0;i < n; i++){
            ha = haha[num[i]];
            he = pow2[i] - ha;
            if(he < 0) he += mod;
            sum1 = (ll)he*pow2[n-i-1]%mod*num[i]%mod;
            ans += sum1;
            if(ans >= mod) ans -= mod;
            ha += pow2[i];
            if(ha >= mod) ha -= mod;
            haha[num[i]] = ha;
        }
        ans %= mod;
        if(ans < 0) ans += mod;
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GDRetop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值