51nod1376 最长递增子序列的数量
来源:互联网 发布:淘宝直通车上分 编辑:程序博客网 时间:2024/06/05 10:48
做法类似上个题.
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int mod=1000000007;int dp[50010][2],a[50010];struct Tree{ int l,r,val,mx;}tree[50000<<2];void create(int l,int r,int k){ tree[k].l=l; tree[k].r=r; tree[k].val=0; tree[k].mx=-1; if(l==r) return; int m=l+r>>1; create(l,m,k<<1); create(m+1,r,k<<1|1);}Tree ret;void seek(int l,int r,int k){ if(l==tree[k].l&&r==tree[k].r) { if(tree[k].mx>ret.mx) ret=tree[k]; else if(tree[k].mx==ret.mx) ret.val=(ret.val+tree[k].val)%mod; return; } int m=tree[k].l+tree[k].r>>1; if(r<=m) seek(l,r,k<<1); else if(l>m) seek(l,r,k<<1|1); else { seek(l,m,k<<1); seek(m+1,r,k<<1|1); }}void update(int x,int val,int len,int k){ if(tree[k].l==tree[k].r) { if(tree[k].mx==len) tree[k].val=(tree[k].val+val)%mod; else if(tree[k].mx<len) tree[k].mx=len,tree[k].val=val; return; } int m=tree[k].l+tree[k].r>>1; if(x<=m) update(x,val,len,k<<1); else update(x,val,len,k<<1|1); if(tree[k<<1].mx>tree[k<<1|1].mx) tree[k].mx=tree[k<<1].mx,tree[k].val=tree[k<<1].val; else if(tree[k<<1].mx<tree[k<<1|1].mx) tree[k].mx=tree[k<<1|1].mx,tree[k].val=tree[k<<1|1].val; else tree[k].mx=tree[k<<1].mx,tree[k].val=(tree[k<<1].val+tree[k<<1|1].val)%mod;}map<int,int>mp;map<int,int>::iterator it;int main(){ freopen("in","r",stdin); int n,m=0; cin>>n; for(int i=0;i<n;i++) { scanf("%d",a+i); mp[a[i]]; } for(it=mp.begin();it!=mp.end();it++) it->second=++m; create(0,m,1); for(int i=0;i<n;i++) { ret.mx=-1; seek(0,mp[a[i]]-1,1); if(ret.mx==-1) { dp[i][0]=dp[i][1]=1; update(mp[a[i]],1,1,1); if(i>0) { if(dp[i][0]==dp[i-1][0]) dp[i][1]=(dp[i][1]+dp[i-1][1])%mod; else if(dp[i][0]<dp[i-1][0]) dp[i][0]=dp[i-1][0],dp[i][1]=dp[i-1][1]; } continue; } ret.mx++; update(mp[a[i]],ret.val,ret.mx,1); if(ret.mx>dp[i-1][0]) dp[i][0]=ret.mx,dp[i][1]=ret.val; else if(ret.mx==dp[i-1][0]) dp[i][0]=ret.mx,dp[i][1]=(dp[i-1][1]+ret.val)%mod; else dp[i][0]=dp[i-1][0],dp[i][1]=dp[i-1][1]; } cout<<dp[n-1][1]; return 0;}
基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
数组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示例
513204
Output示例
2
0 0
- 51nod1376 最长递增子序列的数量
- 51nod1376 最长递增子序列的数量
- 最长递增子序列的数量
- 51Nod-1376-最长递增子序列的数量
- 51Nod 1376 最长递增子序列的数量(dp+树状数组)
- 51nod 1376 最长递增子序列的数量(dp、CDQ分治 | BIT)
- 51nod 1376 最长递增子序列的数量 树状数组
- 51 nod 1376 最长递增子序列的数量(二维偏序cdq)
- NOIP模拟降雷皇&51nod 1376 最长递增子序列的数量
- 1376 最长递增子序列的数量(线段树加DP)
- 1376 最长递增子序列的数量(dp+线段树优化)
- 最长递增子序列
- 最长递增子序列
- 最长递增子序列
- 最长递增子序列
- 最长递增子序列
- 最长递增子序列
- 最长递增子序列
- Linux进程间通信—无名管道和命名管道
- 《字典树》数组模版
- Sharing Memory—Automatically
- opencv图像结构体之间的转换
- Android使用BitmapFactory.Options压缩图片解决加载大图片内存溢出
- 51nod1376 最长递增子序列的数量
- Linux 系统下查看硬件信息命令大全
- LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 工厂模式坑爹题目
- 《策略思维》读后感
- java web 过滤器
- openjudge 百练 2802 小游戏
- 2015年省赛 B Team Formation【位运算】
- 简单实用的误差解决方案 - 兜底