B - Sereja and Subsequences
Sereja has a sequence that consists of n positive integers, a1, a2, ..., an.
First Sereja took a piece of squared paper and wrote all distinct non-empty non-decreasing subsequences of sequence a. Then for each sequence written on the squared paper, Sereja wrote on a piece of lines paper all sequences that do not exceed it.
A sequence of positive integers x = x1, x2, ..., xr doesn't exceed a sequence of positive integers y = y1, y2, ..., yr, if the following inequation holds: x1 ≤ y1, x2 ≤ y2, ..., xr ≤ yr.
Now Sereja wonders, how many sequences are written on the lines piece of paper. Help Sereja, find the required quantity modulo 1000000007 (109 + 7).
Input
The first line contains integer n (1 ≤ n ≤ 105). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106).
Output
In the single line print the answer to the problem modulo 1000000007 (109 + 7).
Examples
Input
1 42
Output
42
Input
3 1 2 2
Output
13
Input
5 1 2 3 4 5
Output
719
题意:给你一个序列,要你写出它的所有子序列,并求它的所有子序列的价值和,所谓价值和就是该子序列所有元素的乘积
分析:设dp[i]表示以位置i结尾的子序列的最大价值和,可以递推出,dp[i]=前i-1的所有子序列的价值和乘以a[i]+单独以a[i]为一个子序列的价值(就是a[i]),还要注意要去重,如果子序列含有重复的数,要把以它为结尾的子序列的最大价值和减掉
AC code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn=1e6+5;
const ll mod=1e9+7;
ll c[maxn];
ll dp[maxn];
ll a[maxn];
ll pre[maxn];
ll n;
ll lowbit(ll x)
{
return x&(-x);
}
ll getsum(ll x)
{
ll ans=0;
while(x)
{
ans+=c[x];
ans%=mod;
x-=lowbit(x);
}
return ans%mod;
}
void update(ll x,ll val)
{
while(x<=1000010)///很重要,不是n了,传进来的是a[i]
{
c[x]+=val;
c[x]%=mod;
x+=lowbit(x);
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
memset(dp,0,sizeof dp);
memset(pre,-1,sizeof pre);
for(int i=1;i<=n;i++)
cin>>a[i];
ll ans=0;
for(int i=1;i<=n;i++){
dp[i]=getsum(a[i])*a[i]+a[i];///状态转移dp[i]表示以i结尾的子序列能达到的最大价值和
///所以dp[i]=前i-1的子序列的总价值和再乘上第i个子序列的价值+第i个数
///单独作为一个子序列
if(pre[a[i]]!=-1) dp[i]-=pre[a[i]];///减去重复的
dp[i]=(dp[i]%mod+mod)%mod;///防止dp[i]减重而小于0
ans+=dp[i];
ans=(ans%mod+mod)%mod;
pre[a[i]]=getsum(a[i])*a[i]+a[i];
update(a[i],dp[i]);///每次更新第a[i]位置的值为以i结尾的子序列能达到的最大价值和
}
cout<<(ans%mod+mod)%mod<<endl;
return 0;
}