
分析
经典问题
n 较小时,考虑 g[i] 为第 i 个数为末尾的最长上升子序列的个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| int f[1005]; mint g[1005]; signed main() { int n;cin>>n; vector<int> a(n+1); for(int i = 1;i<=n;i++) cin>>a[i]; g[0] = 1; for(int i = 1;i <= n;i++) for(int j = 0;j < i;j++){ if(a[i] > a[j]){ if(f[i] < f[j]+1) g[i] = g[j]; else if(f[i] == f[j]+1) g[i] += g[j]; f[i] = max(f[i],f[j]+1); } } int t = *max_element(f+1,f+1+n); mint res = 0; for(int i = 1;i <= n;i++){ if(f[i] == t) res += g[i]; } cout << res.get() << endl; return 0; }
|
对于本题 1<=n<=4e5 , 规定
mx[i] 表示以 i 结尾的最长上升子序列的长度, cnt[i] 对应这个长度的个数
由于最长上升子序列满足偏序关系,算法学习笔记(20): 二维偏序
我们可以用树状数组来维护以 i 结尾的最长上升子序列的长度 mx[]和其对应的长度的个数cnt[]
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| const int mod = 1e9+7; int n; int cnt[400005],mx[400005];
int lwb(int x){ return x & -x; } void add(int p,int v,int len){ for(int i = p; i<= n;i+=lwb(i)){ if(mx[i] < v){ mx[i] = v; cnt[i] = len; } else if(mx[i] == v){ cnt[i] = (cnt[i] + len)%mod; } } }
pair<int,int> ask(int p){ pair<int,int> res = {0,0}; for(int i = p;i;i-=lwb(i)){ if(res.first < mx[i]){ res.first = mx[i]; res.second = cnt[i]; } else if (res.first == mx[i]){ res.second = (res.second + cnt[i])%mod; } } return res; }
signed main() { cin>>n; vector<int> a(n+1),b(n+1); for(int i = 1;i <= n;i++) cin >> a[i],b[i] = a[i]; sort(b.begin()+1,b.end()); b.erase(unique(b.begin()+1,b.end()),b.end()); for(int i = 1;i <= n;i++) a[i] = lower_bound(b.begin()+1,b.end(),a[i]) - b.begin();
int maxn = 0; vector<pair<int,int>> ans; for(int i = 1;i <= n;i++){ auto t = ask(a[i]-1); maxn = max(maxn,t.first+1); if(! t.second ) t.second = 1; ans.push_back({t.first+1,t.second}); add(a[i],t.first+1,t.second); } int res = 0; for(auto i:ans){ if(i.first == maxn) res = (res + i.second)%mod; } cout << res << endl; return 0; }
|