LightOJ 1085 - All Possible Increasing Subsequences 树状数组+离散

http://www.lightoj.com/volume_showproblem.php?problem=1085

题意:求一个序列的递增子序列个数。

思路:找规律可以发现,某个数作为末尾数的种类数为所有比它小的数的情况+1。使用树状数组查找即可。 C++11 的auto在Lightoj上不能用/.\

/** @Date    : 2016-12-01-21.58
  * @Author  : Lweleth ([email protected])
  * @Link    : https://github.com/
  * @Version :
  */

#include<bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const int mod = 1000000007;

int C[N], a[N];

void add(int p, int v)
{
    while(p < N)
    {
        C[p] += v;
        C[p] %= mod;
        p += (-p) & p;
    }
}

int sum(int p)
{
    int ans = 0;
    while(p)
    {
        ans += C[p];
        ans %= mod;
        p -= (-p) & p;
    }
    return ans;
}
int main()
{
    int T;
    int cnt = 0;
    cin >> T;
    while(T--)
    {
        MMF(C);
        int n;
        scanf("%d", &n);

        map<int , int>q;

        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            q[a[i]] = 1;
        }

        int c = 1;
        for(auto i = q.begin(); i != q.end(); i++)
            i->se = c++;

        /*map<int , int>::iterator it;
        for( it = q.begin(); it != q.end(); it++)
            it->se = c++;*/
        for(int i = 1; i <= n; i++)//找规律可以发现,某个数作为末尾数的种类数为所有比它小的数的情况+1
        {
            int x = q[a[i]];
            add(x, sum(x - 1) + 1);
        }
        printf("Case %d: %d\n", ++cnt, sum(c - 1));
    }
    return 0;
}
时间: 2024-08-24 05:15:23

LightOJ 1085 - All Possible Increasing Subsequences 树状数组+离散的相关文章

LightOJ 1085 - All Possible Increasing Subsequences (离散化+树状数组+dp)

1085 - All Possible Increasing Subsequences   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 64 MB An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the following properties hold i1 <

HDU - 2227 Find the nondecreasing subsequences (树状数组 + 子序列 + 离散化)

HDU - 2227 Find the nondecreasing subsequences Time Limit: 5000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For exa

Codeforces 597C. Subsequences (树状数组+dp)

题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长度为j的上升子序列个数,但是dp数组是在树状数组的update函数中进行更新. update(i, val, j)函数表示在i的位置加上val,更新dp[i][j]. sum(i, j)就是求出末尾数字小于等于i 且长度为j的子序列有多少个. 1 //#pragma comment(linker,

hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)

题目链接:点击打开链接 题意描述:给定一个序列,找出其中递增子序列的数量? 解题思路: 1.dp[i]:表示以元素i结尾的子序列的数量,则d[j]=sum(d[i])+1;其中(j>=i且j的下标大于i) 2.此刻我们可以联想到树状数组,按数组下标从小到大的顺序插入元素,那么d[j]就等于sum(j)+1; 3.由于数据范围比较大,我们采用离散化处理即可 代码: #include <cstdio> #include <algorithm> #include <cstri

POJ 2299 Ultra-QuickSort(树状数组 + 离散)

链接:http://poj.org/problem?id=2299 题意:给出N个数组成的数列A(0 <= A[i] <= 999,999,999),求该数列逆序对的数量. 分析:题目所谓的排序过程其实就是一个冒泡排序的过程.在这里,我们需要知道,冒泡排序所需交换的次数等于该序列逆序对的数量(证明略).这是这道题的一个切入点. 树状数组可以很方便地求出数列的前缀和,对于一个数x,我们使树状数组上第x个元素的值赋为1,这时调用Sum(x)就可以得到一个从第1项到第x项的前缀和.这意味着我们可以通

LightOJ 1085(树状数组+离散化+DP,线段树)

All Possible Increasing Subsequences Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Appoint description: Description An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the followi

【Codeforces】Gym 101156E Longest Increasing Subsequences LIS+树状数组

题意 给定$n$个数,求最长上升子序列的方案数 根据数据范围要求是$O(n\log n)$ 朴素的dp方程式$f_i=max(f_j+1),a_i>a_j$,所以记方案数为$v_i$,则$v_i=v_i+v_j,(f_i=f_j+1)$,利用lis的$O(n\log n)$树状数组做法同时维护长度和方案数 从通酱博客里还看到更详尽的解释:stackoverflow 时间复杂度$O(n\log n)$ 代码 #include <bits/stdc++.h> using namespace

codeforces 597C C. Subsequences(dp+树状数组)

题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output For the given sequence with n different elements find the number of increasing subsequences with k + 1 elements. It is

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p