zoukankan      html  css  js  c++  java
  • 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 guaranteed that the answer is not greater than 8·10^18.

    Input
     

    First line contain two integer values n and k (1 ≤ n ≤ 10^5, 0 ≤ k ≤ 10) — the length of sequence and the number of elements in increasing subsequences.

    Next n lines contains one integer ai (1 ≤ ai ≤ n) each — elements of sequence. All values ai are different.

    Output
     

    Print one integer — the answer to the problem.

    Examples

    input
    5 2
    1
    2
    3
    5
    4
    output
    7

    题意:

    问在有n个不同的数组成的序列中,有k+1个数的递增子序列的个数是多少;

    思路:
      
    k不大n也不大看起来好像是dp,假设dp[i][j]表示在前i个数中长度为j的递增子序列并且a[i]是这个序列的最后一位的个数;
       ans[j]=dp[1][j]+dp[2][j]+...+dp[n][j];
       dp[i][j]=dp[x][j-1](x为按a[]序列中数值比它小且在它前面的)
    举一个例子:第一行为输入的a[]第二行为最后一个为递增子序列且最后位为a[i]的个数,再把第二行做成一个树状数组再查询,k-1次后就得到结果
    6 10 9 7 1 2 8 5 4 3 ans
    0 1 1 1 0 1 4 2 2 2 14
    0 0 0 0 0 0 2 1 1 1 5

    AC代码:
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+4;
    int a[N],n,k;
    long long dp[N],sum[N],b[N];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,long long num)
    {
        while(x<=n)
        {
            sum[x]+=num;
            x+=lowbit(x);
        }
    }
    long long query(int x)
    {
        long long s=0;
        while(x>0)
        {
            s+=sum[x];
            x-=lowbit(x);
        }
        return s;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            b[i]=1;
            scanf("%d",&a[i]);
            dp[i]=query(a[i]);
            update(a[i],b[i]);
        }
        for(int i=2;i<=k;i++)
        {
            memset(sum,0,sizeof(sum));
            for(int j=1;j<=n;j++)
            {
                b[j]=dp[j];
                dp[j]=query(a[j]);
                update(a[j],b[j]);
            }
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            ans+=dp[i];
        }
        if(!k)cout<<n<<"
    ";//注意k==0的情况
        else cout<<ans<<"
    ";
        return 0;
    }
     
  • 相关阅读:
    各IDE快捷键
    java的GUI之SWT框架 JavaFX框架 配置开发环境(包含但不限于WindowBuilder完整教程,解决Unknown GUI toolkit报错,解决导入SWT包错误)
    20180314 一个浮点数问题
    20180309 算最近新的感悟吧
    20171228 C#值类型和引用类型
    20171129 ASP.NET中使用Skin文件
    20171123初学demo爬去网页资料
    20171018 在小程序页面去获取用户的OpenID
    20171018 微信小程序客户端数据和服务器交互
    20171012 动态爬虫爬取预约挂号有号信息
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5316729.html
Copyright © 2011-2022 走看看