听说好像灌水区人多...救救孩子
  • 板块灌水区
  • 楼主Ackoter
  • 当前回复22
  • 已保存回复22
  • 发布时间2020/7/24 15:08
  • 上次更新2023/11/6 22:24:50
查看原帖
听说好像灌水区人多...救救孩子
13805
Ackoter楼主2020/7/24 15:08

题目是给n(n<=5000)个数,求长度为m(m<=100)的严格上升子序列个数(不必连续),前三个点AC,后面全是5000,100的点RE...

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<list>
#include<map>
#define lkid (now<<1)
#define rkid (now<<1)|1
#define mid ((L+R)>>1)
using namespace std;
int n,m,b[50001],a[50001],ma;
const int mode=1000000007; 
map<int,int>mapp;
struct p{
    int dp[201];
}tree[80001],nu;
p add(p a,p b)
{
    p azhe;
    for(int i=0;i<=n;i++) azhe.dp[i]=(a.dp[i]+b.dp[i])%mode;
    return azhe;
}
p down(p a)
{
    p azhe;
    azhe.dp[0]=0;
    for(int i=1;i<=n;i++) azhe.dp[i]=a.dp[i-1];
    return azhe; 
}
p finds(int L,int R,int now,int l,int r)
{
    if(l>r) return nu;
    if(L>r||R<l) return nu;
    if(l<=L&&R<=r) return tree[now];
    return add(finds(L,mid,lkid,l,r),finds(mid+1,R,rkid,l,r));
}
void updata(int L,int R,int now,int C)
{
    if(L==R)
    {
        tree[now]=add(tree[now],down(finds(1,ma,1,1,C-1)));
        tree[now].dp[1]=(tree[now].dp[1]+1)%mode;
        return;
    }
    if(C<=mid) updata(L,mid,lkid,C); else updata(mid+1,R,rkid,C);
    tree[now]=add(tree[lkid],tree[rkid]);
    return;
}
int main()
{
//  freopen("seq.in","r",stdin);
//  freopen("seq.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i]; 
    } 
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++) if(mapp[b[i]]==0) mapp[b[i]]=i;
    for(int i=1;i<=n;i++)
    {
        a[i]=mapp[a[i]];
        ma=max(ma,a[i]);
    }
    for(int i=1;i<=n;i++)
        updata(1,ma,1,a[i]);
    cout<<tree[1].dp[m];
    return 0;
}
2020/7/24 15:08
加载中...