• 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
    ",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 }
    油!油!you@
  • 相关阅读:
    为什么linux下多线程程序如此消耗虚拟内存【转】
    具体解说Android的图片下载框架UniversialImageLoader之磁盘缓存的扩展(二)
    【leetcode】Longest Common Prefix
    oracle插入特殊字符&#39;&amp;&#39;问题
    tomcat下配置https环境
    .NET--接口设计
    Hibernate知识点总结
    VB.NET中DataGridView控件
    eclipse内存溢出报错:java.lang.OutOfMemoryError:Java heap space
    理论与实际相结合——三层架构解析
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5454489.html
Copyright © 2020-2023  润新知