Testing Round #12:C(dp+树状数组)

dp[i][j]表示以i结尾,长度为j的序列个数

dp[i][j]=dp[k][j-1](k=0.1.....i-1)

用树状数组求和

要注意的一点就是在读入一个数的时候就进行update以及求和,这样保证其后的序列对其无影响。

具体看代码

#include"cstdio"
#include"queue"
#include"cmath"
#include"stack"
#include"iostream"
#include"algorithm"
#include"cstring"
#include"queue"
#include"vector"
#define ll long long

using namespace std;
const int MAXN = 1e5+50;
const int MAXE = 200500;
const int INF = 0x3f3f3f;

ll dp[MAXN][11];
int lowbit(int x){
    return x&-x;
}

ll sum(int x,int j){
    ll tot=0;
    for(int i=x;i>0;i-=lowbit(i)) tot+=dp[i][j];

    return tot;
}

void update(int x,int j,ll v){
    for(int i=x;i<MAXN;i+=lowbit(i)) dp[i][j]+=v;
}


int main(){
    //freopen("in.txt","r",stdin);
    int n,k;scanf("%d%d",&n,&k);k++;
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++){
        ll t,s;
        scanf("%I64d",&t);
        update(t,1,1);//dp[t][1]=1;
        for(int j=2;j<=k;j++){
            s=sum(t-1,j-1);
            update(t,j,s);//dp[t][j]+=s
        }
    }
    ll ans=sum(n,k);
    printf("%I64d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/luxiaoming/p/5074302.html