【CF314C】Sereja and Subsequences(DP,树状数组)

题意:给定一个N个数的数列,求所有不同不下降子序列的乘积之和,其中不同指的是组成它的数字和长度不完全相同

n (1 ≤ n ≤ 10^5) a[i]<=10^6

思路:考虑DP。设DP[a[i]]为最后一位为a[i]时所有序列的积之和,则dp[a[i]]=a[i]+sigma(dp[a[j]]) *a[i] (a[j]<=a[i],j<i)

后一部分可以用树状数组计算

为了去除最后一位相同的序列比如1 2 2 这个序列中1 2这个子序列只能算一遍

要强行去掉原来最后一位为a[i]的序列

 1 const mo=1000000007;
 2 var dp:array[1..1100000]of int64;
 3     n,i:longint;
 4     s1,s2,t,ans,x:int64;
 5 
 6 function lowbit(x:longint):longint;
 7 begin
 8  exit(x and (-x));
 9 end;
10 
11 function sum(x:longint):int64;
12 var t:int64;
13 begin
14  t:=0;
15  while x>0 do
16  begin
17   t:=(t+dp[x]) mod mo;
18   x:=x-lowbit(x);
19  end;
20  exit(t);
21 end;
22 
23 procedure add(x,s:longint);
24 begin
25  while x<=1000000 do
26  begin
27   dp[x]:=(dp[x]+s) mod mo;
28   x:=x+lowbit(x);
29  end;
30 end;
31 
32 
33 begin
34  //assign(input,'314C.in'); reset(input);
35  //assign(output,'314C.out'); rewrite(output);
36  readln(n);
37  for i:=1 to n do
38  begin
39   read(x);
40   s1:=sum(x); s2:=sum(x-1);
41   t:=(s1+1) mod mo*(x mod mo) mod mo;
42   t:=(t-(s1-s2) mod mo) mod mo;
43   t:=(t+mo) mod mo;
44   add(x,t);
45   ans:=(ans+t) mod mo;
46  end;
47  writeln(ans);
48  //close(input);
49  //close(output);
50 end.

 

posted on 2016-11-23 19:30  myx12345  阅读(307)  评论(0编辑  收藏  举报

导航