p1994
也要提供一下原题面:
一句话题意:找长为5的lis的方案数.
考虑到长度只有5,可以写五个树状数组维护记录长为1,2,3,4,5时最后一个元素小于i的方案数sum(i).对于数a[i],先查长为1的数里小于a[i]的方案数.如果为0就算了,否则把这些方案数加到长为2的树状数组里.一直进行这样的操作即可.
最后输出第五个树状数组的全部的和即可.
具体实现都好吧,写五次而已,也就是80行?时间复杂度最多询问修改五次大概是10*nlog50000;
int t,n; long long now; long long ans; long long c[10][50010]; inline int lowbit(int x) { return x&(-x); } inline long long sum(int a,int x) { ans=0; for(x--;x;x-=lowbit(x)) ans+=c[a][x]; return ans; } inline void add(int a,int x,long long k) { for(;x<=50000;x+=lowbit(x)) c[a][x]+=k; } int main() { //freopen("123.in","r",stdin); n=read(); for(;n;n--) { t=read(); add(1,t,1); now=sum(1,t); if(!now)continue; add(2,t,now); now=sum(2,t); if(!now)continue; add(3,t,now); now=sum(3,t); if(!now)continue; add(4,t,now); now=sum(4,t); if(!now)continue; add(5,t,now); } cout<<sum(5,50001); }