a53

roocks

a53
Apr 19th, 2019
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.53 KB | None | 0 0
  1. #include <fstream>
  2. #include <string>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cstring>
  6. #define nmax 1002
  7. using namespace std;
  8.  
  9. string A[nmax];
  10. int B[21];
  11. vector<int> masks[21];
  12. int markedRow[nmax], markedCol[nmax];
  13. int ways[2][1 << 18], waysO[nmax], waysH[nmax], waysV[nmax];
  14. int comb[nmax][nmax], aranj[nmax][nmax];
  15. int MOD = 1e6 + 3;
  16.  
  17. int countBits(int x)
  18. {
  19. int n = 0;
  20. for (; x; x &= (x - 1), n++);
  21. return n;
  22. }
  23.  
  24. int main()
  25. {
  26. ifstream f("rooks.in");
  27. ofstream g("rooks.out");
  28. int M, N, M1, N1;
  29.  
  30. f >> M >> N;
  31. for (int i = 0; i < M; i++)
  32. f >> A[i];
  33.  
  34. // mark the rows & cols containing restrictions
  35. for (int i = 0; i < M; i++)
  36. for (int j = 0; j < N; j++)
  37. if (A[i][j] == '#') markedRow[i] = markedCol[j] = 1;
  38.  
  39. // swap rows
  40. M1 = 0;
  41. for (int i = 0; i < M; i++)
  42. if (markedRow[i]) swap(A[i], A[M1++]);
  43.  
  44. // swap columns
  45. N1 = 0;
  46. for (int i = 0; i < N; i++)
  47. if (markedCol[i])
  48. {
  49. for (int j = 0; j < M; j++) swap(A[j][i], A[j][N1]);
  50. N1++;
  51. }
  52.  
  53. // pack all the available positions in a row in a 32bit integer
  54. for (int i = 0; i < M1; i++)
  55. for (int j = 0; j < N1; j++)
  56. if (A[i][j] == '.') B[i] |= (1 << j);
  57.  
  58. // precompute the configurations grouped by number of bits/rooks
  59. for (int rooks = 0; rooks < (1 << N1); rooks++)
  60. masks[countBits(rooks)].push_back(rooks);
  61.  
  62. // solve the top-left region
  63. int *curr = ways[0];
  64. int *next = ways[1];
  65. curr[0] = 1;
  66. for (int i = 0; i < M1; i++)
  67. {
  68. // take into account only the configurations with at most i rooks
  69. for (int p = 0; p <= i; p++)
  70. for (int q = 0; q < masks[p].size(); q++)
  71. {
  72. int rooks = masks[p][q];
  73.  
  74. // no extra rook used in the next row
  75. next[rooks] = (next[rooks] + curr[rooks]) % MOD;
  76.  
  77. // try to use a rook in the next row
  78. int available = B[i] & (~rooks);
  79. while (available)
  80. {
  81. // add the last available column/bit to the current configuration
  82. int newRooks = rooks | (available & (-available));
  83.  
  84. // combine configurations
  85. next[newRooks] = (next[newRooks] + curr[rooks]) % MOD;
  86.  
  87. // reset the last bit from the available possibilities
  88. available &= (available - 1);
  89. }
  90. }
  91. swap(curr, next);
  92. memset(next, 0, (1 << N1) * sizeof(int));
  93. }
  94.  
  95. // count number of configurations for the top-left region using a given number of rooks
  96. for (int rooks = 0; rooks < (1 << N1); rooks++)
  97. {
  98. int r = countBits(rooks);
  99. waysO[r] = (waysO[r] + curr[rooks]) % MOD;
  100. }
  101. // count number of configuration for an empty region using a given number of rooks
  102. comb[0][0]=1; comb[1][0]=1; comb[1][1]=1;
  103. aranj[0][0]=1; aranj[1][0]=1; aranj[1][1]=1;
  104. for(int i=2;i<=1000;i++){
  105. comb[i][0]=1; comb[i][i]=1;
  106. for(int j=1;j<=i-1;j++) comb[i][j]=(comb[i-1][j-1]+comb[i-1][j])%MOD;
  107. aranj[i][0]=1;
  108. for(int j=1;j<=i;j++) aranj[i][j]=((long long)aranj[i-1][j-1]*i)%MOD;
  109. }
  110. // extend to the right
  111. for (int r1 = 0; r1 <= min(M1, N1); r1++)
  112. for (int r2 = 0; r2 <= min(M1 - r1, N - N1); r2++)
  113. waysH[r1 + r2] = (waysH[r1 + r2] + waysO[r1] * (long long)comb[M1 - r1][r2] % MOD * (long long)aranj[N - N1][r2]) % MOD;
  114.  
  115. // extend to the bottom
  116. for (int r1 = 0; r1 <= min(M1, N); r1++)
  117. for (int r2 = 0; r2 <= min(M - M1, N - r1); r2++)
  118. waysV[r1 + r2] = (waysV[r1 + r2] + waysH[r1] * (long long)comb[M - M1][r2] % MOD * (long long)aranj[N - r1][r2]) % MOD;
  119.  
  120. // compute the result
  121. int ans = 0;
  122. for (int r = 0; r <= min(M, N); r++)
  123. ans = (ans + waysV[r]) % MOD;
  124. g << ans;
  125.  
  126. return 0;
  127. }
Advertisement
Add Comment
Please, Sign In to add comment