码迷,mamicode.com
首页 > 其他好文 > 详细

Problem 2236 第十四个目标

时间:2016-05-03 14:32:56      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:

技术分享 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<stdlib.h>
 5 #include<string.h>
 6 using namespace std;
 7 typedef long long LL;
 8 LL ans[100005];
 9 const int N=1e9+7;
10 typedef struct pp
11 {
12         int x;
13         int id;
14 } ss;
15 bool cmp(pp n,pp m)
16 {
17         return n.x<m.x;
18 }
19 ss aa[100005];
20 LL dp[100005];
21 LL bit[100005];
22 int cnt=1;
23 LL  sum(int i);
24 void add(int i,LL x);
25 int main(void)
26 {
27         int i,j,k;
28         while(scanf("%d",&k)!=EOF)
29         {
30                 cnt=1;
31                 memset(bit,0,sizeof(bit));
32                 for(i=0; i<k; i++)
33                 {
34                         scanf("%d",&aa[i].x);
35                         aa[i].id=i+1;
36                 }
37                 sort(aa,aa+k,cmp);
38                 ans[aa[0].id]=1;
39                 int cc=aa[0].x;
40                 for(i=1; i<k; i++)
41                 {
42                         if(aa[i].x!=cc)
43                         {
44                                 cc=aa[i].x;
45                                 cnt++;
46                         }
47                         ans[aa[i].id]=cnt;
48                 }
49                 dp[0]=0;
50                 for(i=1; i<100005; i++)
51                         dp[i]=1;
52                 LL nn=0;
53                 for(i=1; i<=k; i++)
54                 {
55                         dp[i]=(dp[i]+sum(ans[i]-1))%N;
56                         nn=(nn+dp[i])%N;
57                         add(ans[i],dp[i]);
58                 }
59                 printf("%lld\n",nn);
60         }
61         return 0;
62 }
63 LL  sum(int i)
64 {
65         LL s=0;
66         while(i>0)
67         {
68                 s=(s+bit[i])%N;
69                 i-=(i&-i);
70         }
71         return s;
72 }
73 void add(int i,LL x)
74 {
75         while(i<=cnt)
76         {
77                 bit[i]=(bit[i]+x)%N;
78                 i+=(i&(-i));
79         }
80 }

 

Problem 2236 第十四个目标

标签:

原文地址:http://www.cnblogs.com/zzuli2sjy/p/5454489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!