码迷,mamicode.com
首页 > 其他好文 > 详细

最长递增子序列的数量 51Nod - 1376

时间:2018-01-21 23:55:01      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:splay   维护   close   nbsp   log   ==   net   http   c++   

最长递增子序列的数量

51Nod - 1376
 
dp...用树状数组维护一下len和cnt
 
技术分享图片
 1 //树状数组 dp
 2 //求LIS的数量
 3 #include <bits/stdc++.h>
 4 using namespace std;
 5 
 6 const int mod = 1e9 + 7;
 7 const int maxn = 50010;
 8 struct Node{
 9     int len, cnt;
10     Node(int len = 0, int cnt = 0) : len(len), cnt(cnt){}
11     Node operator + (const Node &t) const{
12         if(len < t.len) return t;
13         if(len > t.len) return (*this);
14         return Node(len, (cnt + t.cnt) % mod);
15     }
16 };
17 struct Info{
18     int x, pos;
19     bool operator < (const Info &temp) const{
20         if(x == temp.x) return pos > temp.pos;
21         return x < temp.x;
22     }
23 };
24 
25 bool cmp(Info &a, Info &b){
26     if(a.x == b.x) return a.pos > b.pos;
27     return a.x < b.x;
28 }
29 Node c[maxn];
30 Info a[maxn];
31 
32 int n;
33 void add(int i, Node v){
34     for(; i <= n; i += i & -i) c[i] = c[i] + v;
35 }
36 
37 Node sum(int i){
38     Node res;
39     for(; i; i -= i & -i) res = res + c[i];
40     return res;
41 }
42 
43 int main(){
44     while(scanf("%d", &n) != EOF){
45         for(int i = 0; i < n; i++){
46             scanf("%d", &a[i].x);
47             a[i].pos = i + 1;
48         }
49         sort(a, a + n);
50         Node ans;
51         for(int i = 0; i < n; i++){
52             Node temp = sum(a[i].pos);
53             if(++temp.len == 1) temp.cnt = 1;
54             ans = ans + temp;
55             add(a[i].pos, temp);
56         }
57         cout<<ans.cnt<<endl;
58 
59     }
60 }
View Code

 

CDQ写法没看懂=_=

学会了再回来补上。。。

最长递增子序列的数量 51Nod - 1376

标签:splay   维护   close   nbsp   log   ==   net   http   c++   

原文地址:https://www.cnblogs.com/yijiull/p/8325887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!