题目是给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;
}