Problem B. Signed Derangements Input file: derangements.in Output file: derangements.out Time limit: 1 second Memory limit: 256 megabytes Signed permutation of size n is an ordered set of n numbers ranging from −n to n except 0, where absolute values of any two numbers are different. An example of a signed permutation is ⟨4, −2, 3, −5, −1⟩. Clearly, there are 2nn! signed permutations of size n. A signed permutation ⟨a1, a2, . . . , an⟩ is called a signed derangmenent if ai ̸= i for all i. For example, ⟨4, −2, 3, −5, −1⟩ is not a signed derangement, but ⟨4, −2, −3, −5, −1⟩ is. Given n, find the number of signed derangements of size n. Input Input file contains one integer number n (1 ≤ n ≤ 200). Output Output one integer number — the number of signed derangements of size n. Example derangements.in derangements.out 2 5 The following signed 2-permutations are signed derangements: ⟨2, 1⟩, ⟨2, −1⟩, ⟨−2, 1⟩, ⟨−1, −2⟩, and ⟨−2, −1⟩.
容斥原理
import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
/**
* @param args
*/
public static void main(String[] args) throws FileNotFoundException
{
// TODO Auto-generated method stub
Scanner cin = new Scanner (new File("derangements.in"));
PrintWriter cout = new PrintWriter(new File("derangements.out"));
//Scanner cin = new Scanner (System.in);
BigInteger [][] C = new BigInteger [210][210];
BigInteger [] N = new BigInteger [210];
BigInteger [] Two = new BigInteger [210];
BigInteger two;
two=BigInteger.ONE;
two=two.add(two);
C[0][0]=BigInteger.ONE;
for (int i=1;i<=200;i++)
{
C[i][0]=C[i][i]=BigInteger.ONE;
for (int j=1;j<i;j++) {
C[i][j] = BigInteger.ZERO;
C[i][j]=C[i][j].add(C[i-1][j-1]);
C[i][j]=C[i][j].add(C[i-1][j]);
}
}
N[0] = BigInteger.ONE;
for (int i=1;i<=200;i++) {
BigInteger tp = new BigInteger(String.valueOf(i));
N[i] = N[i-1].multiply(tp);
}
Two[0] = BigInteger.ONE;
for (int i=1;i<=200;i++) {
Two[i] = Two[i-1].multiply(two);
}
int n;
n = cin.nextInt();
BigInteger ans = BigInteger.ZERO;
ans=Two[n].multiply(N[n]);
int cur=0;
for (int i=1;i<=n;i++){
if (cur==0) {
BigInteger tp = C[n][i].multiply(Two[n-i]);
tp=tp.multiply(N[n-i]);
ans=ans.subtract(tp);
cur=1-cur;
}
else {
BigInteger tp = C[n][i].multiply(Two[n-i]);
tp=tp.multiply(N[n-i]);
ans=ans.add(tp);
cur=1-cur;
}
}
cout.println(ans);
//System.out.println(ans);
cin.close();
cout.close();
}
}