ZOJ 3896 Permutation (JAVA IO, CRT)

来源:互联网 发布:海角七号七封情书知乎 编辑:程序博客网 时间:2024/06/04 19:36

题意:

给定n的两个排列A和B,还有置换C,问最少需要对A进行多少次置换C才能变成B,不可能则输出Impossible

思路:

思路是比较好想的,难度在于怎么实现。。

对A中每个数A[i],求出它需要经过多少次置换能变成B[i],如果变不了就Impossible。

然后就是用CRT来合并就是答案了。

涨姿势了。。java的输入挂。。

import java.math.*;import java.text.*;import java.util.*;import java.io.*;class Scan {BufferedReader buffer;StringTokenizer tok;Scan() {buffer = new BufferedReader(new InputStreamReader(System.in));tok = null;}boolean hasNext() {while(tok == null || !tok.hasMoreElements()) {try {tok = new StringTokenizer(buffer.readLine());} catch(Exception e) {return false;}}return true;}String next() {if(hasNext()) return tok.nextToken();return null;}int nextInt() {String s = next();return Integer.parseInt(s);}long nextLong() {return Long.parseLong(next());}}public class Main {public static BigInteger K1, K2;public static void exgcd(BigInteger a, BigInteger b) {if(b.compareTo(BigInteger.ZERO) == 0) {K1 = BigInteger.ONE;K2 = BigInteger.ZERO;}else {exgcd(b, a.mod(b));BigInteger tmp = K1;K1 = K2;K2 = tmp;K2 = K2.subtract(a.divide(b).multiply(K1));}}public static void main(String []args) {PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));Scan scan = new Scan();int N = 50020;int a[] = new int[N], b[] = new int[N], c[] = new int[N], n;boolean vis[] = new boolean[N];int pos[] = new int[N];int dep[] = new int[N];int x[] = new int[N];int t[] = new int[N], val[] = new int[N];int mod[] = new int[N];while(scan.hasNext()) {n = scan.nextInt();for(int i = 1; i <= n; ++i) {a[i] = scan.nextInt();pos[a[i]] = i;}for(int i = 1; i <= n; ++i)b[i] = scan.nextInt();for(int i = 1; i <= n; ++i)c[i] = scan.nextInt();for(int i = 1; i <= n; ++i) {vis[i] = false;dep[i] = -1;mod[i] = -1;}boolean flag = true;int tot = 0;for(int i = 1; i <= n; ++i) {if(!vis[a[i]]) {int cnt = 0;int u = c[i];x[++cnt] = a[i];dep[a[i]] = 0;int d = 0;while(u != i) {dep[a[u]] = ++d;vis[a[u]] = true;//System.out.println("dep " + a[u] + " " + dep[a[u]]);x[++cnt] = a[u];u = c[u];}for(int j = 1; j <= cnt; ++j) {//System.out.println("x[j] " + x[j]);int v = pos[x[j]];if(dep[b[v]] == -1) {flag = false;break;}val[++tot] = dep[a[v]] - dep[b[v]];if(val[tot] < 0) val[tot] += cnt;if(mod[cnt] != -1 && mod[cnt] != val[tot]) {flag = false;break;}mod[cnt] = val[tot];}for(int j = 1; j <= cnt; ++j) {int v = pos[x[j]];dep[a[v]] = -1;}if(flag == false) break;}}if(!flag) {System.out.println("Impossible");continue;}BigInteger M1 = BigInteger.ONE;BigInteger B1 = BigInteger.ZERO;for(int i = 2; i <= n; ++i) {if(mod[i] == -1) continue;//System.out.println("i " + i + "mod " + mod[i]);BigInteger M2 = BigInteger.valueOf(i);BigInteger B2 = BigInteger.valueOf(mod[i]);BigInteger g = M2.gcd(M1);BigInteger X = B2.subtract(B1);if(X.mod(g).compareTo(BigInteger.ZERO) != 0) {flag = false;break;}exgcd(M1.divide(g), M2.divide(g));//System.out.println(K1 + " " + K2);K1 = K1.multiply(X.divide(g));B1 = B1.add(K1.multiply(M1));M1 = M1.divide(g).multiply(M2);B1 = B1.mod(M1);if(B1.compareTo(BigInteger.ZERO) < 0) B1 = B1.add(M1);//System.out.println("B1 M1" + B1 + "  " + M1);}if(!flag) {System.out.println("Impossible");continue;}System.out.println(B1);}}}   


0 0
原创粉丝点击