数组A包含N个整数(可能包含相同的值)。设S为A的子序列且S中的元素是递增的,则S为A的递增子序列。如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS)。A的LIS可能有很多个。例如A为:{1 3 2 0 4},1 3 4,1 2 4均为A的LIS。给出数组A,求A的LIS有多少个。由于数量很大,输出Mod 1000000007的结果即可。相同的数字在不同的位置,算作不同的,例如 {1 1 2} 答案为2。
Input
第1行:1个数N,表示数组的长度。(1 <= N <= 50000) 第2 - N + 1行:每行1个数A[i],表示数组的元素(0 <= A[i] <= 10^9)
Output
输出最长递增子序列的数量Mod 1000000007。
Input示例
5 1 3 2 0 4
Output示例
2解题: 直接维护到每一个位置为止的递增长度即可,重载一下加法操作。
#include
#include
#include
#include
#include
#include
using namespace std;
#define mod 1000000007const int maxn =60000;
int n;
intlowbit(int x)
{
return x&(-x);
}struct node
{
int len;
int kind;
node(){len=0;
kind=0;
}
node(int _len,int _kind){len=_len;
kind=_kind;
}
node operator +(const node &tmp)const
{
if(lentmp.pos;
}
return val0)
{
tmp=tmp+b[x];
x-=lowbit(x);
}
return tmp;
}void update(int x,node tp)
{
while(x<=n)
{
b[x]=b[x]+tp;
x+=lowbit(x);
}
}int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
for(int i=1;
i<=n;
i++)
{
scanf("%d",&a[i].val);
a[i].pos=i;
}
sort(a+1,a+n+1);
node tmp,miao;
for(int i=1;
i<=n;
i++)
{
tmp=getsum(a[i].pos);
if(tmp.len==0) tmp.kind=1;
tmp.len++;
update(a[i].pos,tmp);
miao=miao+tmp;
}
//node miao;
//for(int i=1;
i<=n;
i++)
//miao=miao+b[i];
printf("%d\n",miao.kind);
}
return 0;
}
推荐阅读
- 并查集|[CF938G] Shortest Path Queries
- Different Integers
- 倍增|191026考试题解
- 圆方树|uoj#189. 【集训队互测2016】火车司机出秦川 //圆方树
- 树状数组|【HDU6635 Nonsense Time】树状数组维护最长上升子序列