light oj 1085

来源:互联网 发布:js 指定时间转时间戳 编辑:程序博客网 时间:2024/06/05 16:51

All Possible Increasing Subsequences
Time Limit: 3000MSMemory Limit: 65536KB64bit IO Format: %lld & %llu

Submit Status uDebug

Description

An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the following properties hold

1.      i1 < i2 < i3 < ... < ik and

2.      Ai1 < Ai2 < Ai3 < ... < Aik

Now you are given a sequence, you have to find the number of all possible increasing subsequences.

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case contains an integer n (1 ≤ n ≤ 105) denoting the number of elements in the initial sequence. The next line will contain n integers separated by spaces, denoting the elements of the sequence. Each of these integers will be fit into a 32 bit signed integer.

Output

For each case of input, print the case number and the number of possible increasing subsequences modulo 1000000007.

Sample Input

3

3

1 1 2

5

1 2 1000 1000 1001

3

1 10 11

Sample Output

Case 1: 5

Case 2: 23

Case 3: 7

Source

Problem Setter: Jane Alam Jan

这题首先要对树状数组有很好的理解,注意排序时的技巧把序号大的放前面,这样就能保证序列一定是递增的,dp[i]为以结尾的上升子区间和,,,技巧性很强,自行领会


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 100010;
const int mod = 1000000007;
int dp[N], a[N], p[N];
int n;
int lowbit(int k)
{
    return k&(-k);
}
int cmp(int x,int y)
{
    if(a[x]!=a[y])
    {
        return a[x]<a[y];
    }
    else
    {
        return x>y;
    }
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans=(ans+dp[x])%mod;
        x-=lowbit(x);
    }
    return ans;
}
void inser(int x,int v)
{
    while(x<=n)
    {
        dp[x]=(dp[x]+v)%mod;
        x+=lowbit(x);
    }
    return ;
}


int main()
{
    int t, ncase=1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d", &a[i]);
            p[i]=i;
        }
        sort(p+1,p+n+1,cmp);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            inser(p[i],sum(p[i])+1);
        }
        printf("Case %d: %d\n",ncase++,sum(n));
    }
    return 0;
}

0 0