1. 程式人生 > >[BZOJ1264][AHOI2006]基因匹配Match(DP + 樹狀數組)

[BZOJ1264][AHOI2006]基因匹配Match(DP + 樹狀數組)

return scanf namespace onclick ring splay urn ret int

傳送門

有點類似LCS,可以把 a[i] 在 b 串中的位置用一個鏈式前向星串起來,由於鏈式前向星是從後往前遍歷,所以可以直接搞。

狀態轉移方程 f[i] = max(f[j]) + 1 ( 1 <= j < i && a[i] == b[j] )

——代碼

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 const
int MAXN = 200001; 8 int n, cnt, ans; 9 int a[MAXN], c[MAXN]; 10 int head[MAXN], to[MAXN << 4], next[MAXN << 4]; 11 12 inline int query(int x) 13 { 14 int ret = 0; 15 for(; x; x -= x & -x) ret = max(ret, c[x]); 16 return ret; 17 } 18 19 inline void update(int x, int
d) 20 { 21 for(; x <= n; x += x & -x) c[x] = max(c[x], d); 22 } 23 24 inline void add(int x, int y) 25 { 26 to[cnt] = y; 27 next[cnt] = head[x]; 28 head[x] = cnt++; 29 } 30 31 int main() 32 { 33 int i, j, x; 34 scanf("%d", &n); 35 n *= 5; 36 memset(head, -1
, sizeof(head)); 37 for(i = 1; i <= n; i++) scanf("%d", &a[i]); 38 for(i = 1; i <= n; i++) scanf("%d", &x), add(x, i); 39 for(i = 1; i <= n; i++) 40 for(j = head[a[i]]; j != -1; j = next[j]) 41 { 42 x = query(to[j] - 1) + 1; 43 update(to[j], x); 44 ans = max(ans, x); 45 } 46 printf("%d", ans); 47 return 0; 48 }
View Code

[BZOJ1264][AHOI2006]基因匹配Match(DP + 樹狀數組)