HDU 5495 LCS (query set judgment ring)
[General idea ]:
Problem Description You are given two sequence {A1, a2,...,} And {B1, b2,..., bn} . Both sequences are permutation {1, 2,..., n} . You are going to find another permutation {P1, p2,..., pn} Such that the length of LCS (longest common subsequence) {Ap1, ap2,..., apn} And {Bp1, bp2,..., bpn} Is maximum.
Input There are multiple test cases. The first line of input contains an integer T , Indicating the number of test cases. For each test case:
The first line contains an integer N (1 ≤ n ≤ 105) -The length of the permutation. The second line contains N Integers A1, a2,..., . The third line contains N Integers B1, b2,..., bn .
The sum N In the test cases will not exceed 2 × 106 .
Output For each test case, output the maximum length of LCS.
Sample Input
231 2 33 2 161 5 3 2 6 43 6 2 4 5 1
Sample Output
24
[Idea]: There are two arrays in the question, so we can first divide the arrangement into several rings. Obviously, the rings are independent of each other. in fact for a ring with a length of l (l> 1) l (l> 1), we can always get an LCS with a length of l-1l −1, the answer to this question is obvious, that is, nn minus the number of rings with a length greater than 11.
Code:
/** Problem: NO: HDU 5495 * Running time: 764 MS * Complier: G ++ * Author: javaherongwei * Create Time: Sunday */# include
# Include
# Include
# Include
# Include using namespace std; # define min (a, B)
B? A: btypedef long LL; const double eps = 1e-8; const double pi = acos (-1.0); const int maxn = 1e5 + 10; inline LL read () {int c = 0, f = 1; char ch = getchar (); while (ch <'0' | ch> '9 ') {if (ch = '-') f =-1; ch = getchar () ;}while (ch> = '0' & ch <= '9 ') {c = c * 10 + ch-'0'; ch = getchar ();} return c * f;} int fa [maxn]; int st [maxn], sb [maxn], sum [maxn]; bool OK; int Find (int x) {if (x = fa [x]) return x; return fa [x] = Find (fa [x]);} void Merge (int x, int y) {int fx = Find (x ); int fy = Find (y); if (fx = fy) return; else fa [fx] = fy, sum [fy] + = sum [fx]; // count the number of elements below the root node} int main () {int t; t = read (); while (t --) {int n; n = read (); for (int I = 1; I <= n; ++ I) st [I] = read (); for (int I = 1; I <= n; ++ I) sb [I] = read (); for (int I = 1; I <= n; ++ I) sum [I] = 1, fa [I] = I; for (int I = 1; I <= n; ++ I) {Merge (st [I], sb [I]);} int cnt = 0; for (int I = 1; I <= n; ++ I) {if (fa [I] = I) {if (sum [I] = 1) cnt ++; else cnt + = sum [I]-1 ;}} printf (% d, cnt );} return 0 ;}