Problem 2236 第十四个目标

Problem 2236 第十四个目标

Accept: 4    Submit: 6
Time Limit: 1000 mSec    Memory Limit : 32768 KB

Problem Description

目 暮警官、妃英里、阿笠博士等人接连遭到不明身份之人的暗算,柯南追踪伤害阿笠博士的凶手,根据几起案件现场留下的线索发现凶手按照扑克牌的顺序行凶。在经 过一系列的推理后,柯南发现受害者的名字均包含扑克牌的数值,且扑克牌的大小是严格递增的,此外遇害者与毛利小五郎有关。

为了避免下一个遇害者的出现,柯南将可能遭到暗算的人中的数字按关联程度排列了出来,即顺序不可改变。柯南需要知道共有多少种可能结果,满足受害人名字出现的数字严格递增,但是他柯南要找出关键的证据所在,所以这个任务就交给你了。

(如果你看不懂上面在说什么,这题是求一个数列中严格递增子序列的个数。比如数列(1,3,2)的严格递增子序列有(1)、(3)、(2)、(1,3)、(1,2),共5个。长得一样的但是位置不同的算不同的子序列,比如数列(3,3)的答案是2。)

Input

多组数据(<=10),处理到EOF。

第一行输入正整数N(N≤100 000),表示共有N个人。

第二行共有N个整数Ai(1≤Ai≤10^9),表示第i个人名字中的数字。

Output

每组数据输出一个整数,表示所有可能的结果。由于结果可能较大,对1 000 000 007取模后输出。

Sample Input

3 1 3 2

Sample Output

5

Source

福州大学第十三届程序设计竞赛
思路:dp+树状数组优化+离散化;
状态转移方程:dp[i]=sum(dp[j]);a[j]<a[i];
dp[i]表示以a[i]结束呈严格递增的个数;因为每次都要到前面找比当前小的数,所以用树状数组优化下就行。
复杂度为n*(logn);
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string.h>
 5 #include<queue>
 6 #include<math.h>
 7 using namespace std;
 8 typedef long long LL;
 9 const int N=1e9+7;
10 LL  dp[100005];
11 LL  bit[100005];
12 int ak[100005];
13 typedef  struct pp
14 {
15         int x;
16         int id;
17 } ss;
18 ss  ans[100005];
19 bool cmp(pp n, pp m)
20 {
21         return n.x<m.x;
22 }
23 void add(int i,int x,int n);
24 LL BIT(int i);
25 int main(void)
26 {
27         int i,j ,k;
28         int s;int n;
29         while(scanf("%d",&n)!=EOF)
30         {
31                 int m;
32                 for(i=1; i<=n; i++)
33                 {
34                         scanf("%d",&ans[i].x);
35                         ans[i].id=i;
36                 }
37                 sort(ans+1,ans+1+n,cmp);
38                 ak[ans[1].id]=1;
39                 int cn=1;
40                 int dd=ans[1].x;
41                 for(i=2; i<=n; i++)
42                 {
43                         if(dd!=ans[i].x)
44                         {
45                                 cn++;
46                                 dd=ans[i].x;
47                         }
48                         ak[ans[i].id]=cn;
49                 }
50                 memset(bit,0,sizeof(bit));
51                 memset(dp,0,sizeof(dp));
52                 for(i=1; i<=n; i++)
53                 {
54                         dp[i]=BIT(ak[i]-1);
55                         dp[i]=(dp[i]+1)%N;
56                         add(ak[i],dp[i],cn);
57                 }
58                 LL sum=0;
59                 for(i=1; i<=n; i++)
60                 {
61                         sum=(sum+dp[i])%N;
62                 }
63                 printf("%lld\n",sum);
64         }
65         return 0;
66 }
67 LL BIT(int i)
68 {
69         LL s=0;
70         while(i>0)
71         {
72                 s=(s+bit[i])%N;
73                 i-=(i&(-i));
74         }
75         return s;
76 }
77 void add(int i,int x,int n)
78 {
79         while(i<=n)
80         {
81                 bit[i]=(bit[i]+x)%N;
82                 i+=(i&(-i));
83         }
84 }

 

 

posted @ 2016-05-03 12:07  sCjTyC  阅读(197)  评论(0编辑  收藏  举报