P1637 三元上升子序列 题解

复制Markdown  展开
题目描述
Erwin 最近对一种叫 thair 的东西巨感兴趣。。。

在含有 

n 个整数的序列 

1
,

2
,

,



1

 ,a 
2

 ,…,a 
n

  中,三个数被称作thair当且仅当 

<

<

i

<


<



i

  j

  k

 。

求一个序列中 thair 的个数。

输入格式
开始一行一个正整数 

n,

以后一行 

n 个整数 

1
,

2
,

,



1

 ,a 
2

 ,…,a 
n

 。

输出格式
一行一个整数表示 thair 的个数。

输入输出样例
输入 #1复制
4
2 1 3 4
输出 #1复制
2
输入 #2复制
5
1 2 2 3 4
输出 #2复制
7
说明/提示
样例2 解释
7
7 个 thair 分别是:

1 2 3
1 2 4
1 2 3
1 2 4
1 3 4
2 3 4
2 3 4
数据规模与约定
对于 
30
%
30% 的数据 保证 


100
n≤100;
对于 
60
%
60% 的数据 保证 


2000
n≤2000;
对于 
100
%
100% 的数据 保证 
1



3
×
1
0
4
1≤n≤3×10 
4
 ,
1




1
0
5
1≤a 
i

 ≤10 
5
 。

这道题可以拓展到M元上升子序列。
做法: DP + 树状数组优化
仿照



LIS的做法,设

[

]
[

]
f[i][j]为以

[

]
a[j]为结尾的长度为

i的上升子序列的个数。

得到状态转移方程:

[

]
[

]
=


<

,

[

]
<

[

]

[


1
]
[

]
f[i][j]=∑ 
k
 f[i−1][k]

转移时暴力枚举,显然复杂度为

(

2

)
O(N 
2
 M)

考虑到k有两个限制条件,

<

k
[

]
<

[

]
a[k]
[
]
a[]离散化,再用树状数组维护。

具体来说,在外层循环

i,建立一个树状数组,以

[

]
a[k]为下标存储

[


1
]
[

]
f[i−1][k]的值。当内层循环到

j时,

[

]
[

]
+
=



(

[

]

1
)
f[i][j]+=ask(a[j]−1),然后在转移到下一个

j之前



(

[

]
,

[


1
]
[

]
)
add(a[j],f[i−1][j])。 

j从小到大循环保证了

<

k
[


1
]
[


1
]
f[i−1][j−1]的前缀和保证了

[

]
<

[

]
a[k]

复杂度

(






)
O(NMlogN)。

双倍经验:UVA12983





:
CODE:

#include
#include
#include
#include
using namespace std;
typedef long long ll;
ll n, a[30010], s[30010], m, f[4][30010], c[60010], ans;
ll val(int x) { return lower_bound(s+1, s+m+1, x) - s; }
ll ask(int x, ll sum = 0) {
    for(; x; x -= (x & (-x))) sum += c[x];
    return sum;
}
void add(int x, ll v) { for(; x <= m; x += (x & (-x))) c[x] += v; }
int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i],  s[i] = a[i];
    sort(s+1, s+n+1);
    m = unique(s+1, s+n+1) - s - 1;
    for(int i = 1; i <= n; i++) f[1][i] = 1, a[i] = val(a[i]);
    for(int i = 2; i <= 3; i++) {
        memset(c, 0, sizeof(c));
        for(int j = 1; j <= n; j++) {
            f[i][j] = ask(a[j]-1);
            add(a[j], f[i-1][j]);
        }
    }
    for(int i = 1; i <= n; i++) ans += f[3][i];
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(java,算法,javascript)