Codeforces 597C(树状数组 + dp)

原创 2015年11月20日 12:24:54

@(K ACMer)


题意:
由1到n,共n个数构成的序列中长为k + 1的上升子序列有多少个?
分析:
注意到题中数字是1到n,且子序列最长只有11.我们可以这样定义状态:dp[i][j]为长度为i的子序列中,末尾数以j结尾的个数.
那么容易有转移方程:

dp[i][j]=t=1...j1dp[i1][t]
显然这个复杂度是O(kn2)的,过大,注意到我们这里每次都是求的数组的前缀和,那不是用一个树状数组来维护就好了么?这样复杂度就变为了O(knlogn)


code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
typedef unsigned long long ll;
typedef vector<int> vi;
#define xx first
#define yy second
const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 41;
ll dp[12][maxn];
int n, k, ans;

ll sum(int x, int i) {
    ll ret = 0;
    while (i > 0) {
        ret += dp[x][i];
        i -= i & -i;
    }
    return ret;
}

void add(int y, int i, ll x) {
    while (i <= n) {
        dp[y][i] += x;
        i += i & -i;
    }
    return;
}

int main(void) {
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        for (int i = k + 1; i >= 1; i--) {
            ll temp = (i - 1 == 0) ? 1 :sum(i - 1, x - 1);
            add(i, x, temp);
        }
    }
    cout << sum(k + 1, n) << endl;
    return 0;
}
版权声明:本文为博主原创文章,转载请注明作者:jibancanyang。

相关文章推荐

Codeforces 597C Subsequences【Dp+二维树状数组】

C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input s...

Codeforces 597C Subsequences dp + 树状数组

题意 给你n的一个排列,问你包含k个数的子序列个数有多少。 n <= 10^5,k <= 11 思路 dp 状态dp[i][j] 表示前i个数,包含k个数的子序列个数有多少 f[i][j]表示前i个数...

codeforces-597C-Subsequences【树状数组】

597C-Subsequences

597C. Subsequences【DP】【树状数组】

题目链接http://codeforces.com/problemset/problem/597/C思路就是叫你求长度为k+1(直接当k吧,读完加个1就行)的上升子序列个数。设dp[i][j]为以a[...

[dp+树状数组优化] CF597C. Subsequences

题意:给定1~n的一种排列,求长度为k+1的上升子序列的个数。 (0 题解:DP。首先可以很容易的想到DP[i][j],表示以i为结尾长度为j的上升子序列的个数。 也可以很容易的想到转移 DP[i]...

Codeforces_611D:New_Year_and_Ancient_Prophecy(DP+树状数组)

题意是给定一个n位数字,你现在可以将它分隔成若干个长度更短的数字,例如1234567可以拆分成1234和567两个数字,现在规定一个拆分方案合法当且仅当①拆分出的数字按顺序严格递增②拆除的每个数字是正...

【Codeforces Round 333 (Div 2)E】【期望DP概率做法 树状数组转前缀和】Kleofáš and the n-thlon n场比赛m个人获得总名次的期望

E. Kleofáš and the n-thlon time limit per test 1 second memory limit per test 256 megaby...

Codeforces Round 223 380C Sereja and Brackets 树状数组

类似的题目有好多,总结成下面的模型: 一个序列,有tot组点对,固定不变,m次查询[l,r]这个区间上能够完全覆盖多少组点对。 由于这些点对是固定不变的,不支持任何的插入,修改,删除,所以我们采取离线...

Codeforces 383C . Propagating tree【树状数组,dfs】

题目大意: 有一棵树,对这个树有两种操作:1:表示为(1 x val),在编号为x的节点上加上val,然后给x节点的每个儿子加上- val,再给每个儿子的儿子加上-(- val),一直加到没有儿子为止...

CodeForces 383C Propagating tree 树上哈希+树状数组

点击打开链接链接 C. Propagating tree time limit per test 2 seconds memory limit per test 25...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)