• 第十四个目标 (fzu)


     

    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
     
     
    #include<stdio.h>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    #define Lson r<<1
    #define Rson r<<1|1
    
    const int maxn = 1e5+7;
    const int Mod = 1e9+7;
    
    struct node
    {
        int L, R, Mid;
        long long sum;
    }a[maxn<<2];
    
    int val[maxn], Hash[maxn];
    
    void Build(int r, int L, int R)
    {
        a[r].L = L;
        a[r].R = R;
        a[r].Mid = (L+R) / 2;
        a[r].sum = 0;
    
        if(L == R)
            return ;
    
        Build(Lson, L, a[r].Mid);
        Build(Rson, a[r].Mid+1, R);
    }
    ///x位置加上一个值val
    void Insert(int r, int x, int sum)
    {
        (a[r].sum += sum) %= Mod;
    
        if(a[r].L == a[r].R)
            return ;
    
        if(x <= a[r].Mid)
            Insert(Lson, x, sum);
        else
            Insert(Rson, x, sum);
    }
    int Query(int r, int L, int R)
    {
        if(L > R)
            return 0;
    
        if(a[r].L == L && a[r].R == R)
            return a[r].sum;
    
        if(R <= a[r].Mid)
            return Query(Lson, L, R);
        else if(L > a[r].Mid)
            return Query(Rson, L, R);
        else
        {
            int Lval = Query(Lson, L, a[r].Mid);
            int Rval = Query(Rson, a[r].Mid+1, R);
    
            return (Lval+Rval) % Mod;
        }
    }
    
    int main()
    {
        int N;
    
        while(scanf("%d", &N) != EOF)
        {
            for(int i=0; i<N; i++)
            {
                scanf("%d", &val[i]);
                Hash[i] = val[i];
            }
    
            Hash[N] = 0;
    
            sort(Hash, Hash+N+1);
            int hn = unique(Hash, Hash+N+1)-Hash;
    
            Build(1, 1, hn+1);
    
            for(int i=0; i<N; i++)
            {
                int x = lower_bound(Hash, Hash+hn, val[i]) - Hash;
                int sum = Query(1, 1, x-1);
                Insert(1, x, sum+1);
            }
    
            int ans = Query(1, 1, hn+1);
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }

     

  • 相关阅读:
    php -- php数组相关函数
    php -- 数组排序
    php -- in_array函数
    php -- 魔术方法 之 删除属性:__unset()
    无符号整型与有符号整型相运算规则
    N个节点的二叉树有多少种形态
    getopt_long
    typedef
    约瑟夫环问题算法(M)
    C语言基础
  • 原文地址:https://www.cnblogs.com/YY56/p/5452674.html
Copyright © 2020-2023  润新知