#include<cstdio> #include<iostream> #include<sstream> #include<cmath> #include<algorithm> #include<map> #include<set> #include<list> #include<vector> #include<stack> #include<queue> #include<string> #include<iomanip> #include<fstream> #include<ctime> #include<climits> using namespace std; typedef vector<int> VI; typedef pair <int,int> ii; typedef long long LL; #define pb push_back const int MOD = 1000000007; const int N = 3010; bool DEBUG = false; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; int tt[10], n, k, i, j, l, l1, l2, l3, l4, l5, x, y, xa, ya, xb, yb, res, sum, locSum, minu, plu; LL add; bool bOk; char tab[N][N], neigh[N][N][5]; char twos[N][N][4]; int indTwos[N][N]; char t[N]; bool xx[N][N]; vector<ii> wek[5]; set<ii>::iterator it, it2; bool inRange(int a, int b) { return a >= 1 && a <= n && b >= 1 && b <= n; } bool isOk(int a, int b) { return inRange(a, b) && tab[a][b] == -1; } void mark(int m) { int i, j, l; for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (tab[i][j] == m - 1) for (l=0;l<4;l++) if (isOk(i + dx[l], j + dy[l])) { tab[i + dx[l]][j + dy[l]] = m; wek[m].pb(ii(i + dx[l], j + dy[l])); } } void countNeigh() { int i, j, l; for (i=1;i<=n;i++) for (j=1;j<=n;j++) { for (l=0;l<=4;l++) neigh[i][j][l] = 0; indTwos[i][j] = 0; for (l=0;l<4;l++) { if (tab[i + dx[l]][j + dy[l]] != -1) neigh[i][j][tab[i + dx[l]][j + dy[l]]]++; if (tab[i + dx[l]][j + dy[l]] == 2) twos[i][j][indTwos[i][j]++] = l; } } } LL comb(int a, int b) { if (a < b) return 0; if (b == 0) return 1; if (b == 1) return a; int i, j; for (i=0;i<b;i++) tt[i] = a - i; for (j=b;j>=2;j--) { for (i=0;i<b;i++) if (tt[i] % j == 0) { tt[i] /= j; break; } } int res = 1; for (i=0;i<b;i++) res = (res * 1LL * tt[i]) % MOD; return res; } int main() { scanf("%d %d", &n, &k); for (i=0;i<=n+1;i++) for (j=0;j<=n+1;j++) tab[i][j] = -1; for (i=1;i<=n;i++) { scanf("%s", t); for (j=1;j<=n;j++) if (t[j - 1] == '#') tab[i][j] = 0; } for (i=1;i<=k;i++) { wek[i].clear(); mark(i); } /*if (DEBUG) { for (i=1;i<=n;i++) { for (j=1;j<=n;j++) if (tab[i][j]<0) printf("."); else if (tab[i][j]==0) printf("#"); else printf("%d", tab[i][j]); printf("\n"); } }*/ countNeigh(); res = 0; if (k == 1) { // 1 res += wek[1].size(); } else if (k == 2) { // 1 1 if (DEBUG) printf("possibility 1 1\n"); res = comb(wek[1].size(), 2); if (DEBUG) printf("%d\n", res); // 1 2 if (DEBUG) printf("possibility 1 2\n"); for (i=0;i<wek[1].size();i++) { res += neigh[wek[1][i].first][wek[1][i].second][2]; } res %= MOD; if (DEBUG) printf("%d\n", res); } else if (k == 3) { // 1 1 1 if (DEBUG) printf("possibility 1 1 1\n"); res = comb(wek[1].size(), 3); if (DEBUG) printf("%d\n", res); // 1 1 2 if (DEBUG) printf("possibility 1 1 2\n"); for (i=0;i<wek[2].size();i++) { x = wek[2][i].first; y = wek[2][i].second; res += comb(neigh[x][y][1], 2); res = (neigh[x][y][1] * 1LL * (wek[1].size() - neigh[x][y][1]) + res) % MOD; } if (DEBUG) printf("%d\n", res); // 1 2 2 if (DEBUG) printf("possibility 1 2 2\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; res += comb(neigh[x][y][2], 2); for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { res += neigh[x + dx[l]][y + dy[l]][2]; } } res %= MOD; if (DEBUG) printf("%d\n", res); // 1 2 3 if (DEBUG) printf("possibility 1 2 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { res += neigh[x + dx[l]][y + dy[l]][3]; } } res %= MOD; if (DEBUG) printf("%d\n", res); } else if (k == 4) { sum = 0; for (i=0;i<wek[2].size();i++) sum += neigh[wek[2][i].first][wek[2][i].second][1]; // 1 1 1 1 if (DEBUG) printf("possibility 1 1 1 1\n"); res = comb(wek[1].size(), 4); // 1 1 1 2 if (DEBUG) printf("possibility 1 1 1 2\n"); for (i=0;i<wek[2].size();i++) { x = wek[2][i].first; y = wek[2][i].second; res += comb(neigh[x][y][1], 3); res = (comb(neigh[x][y][1], 2) * 1LL * (wek[1].size() - neigh[x][y][1]) + res) % MOD; res = (neigh[x][y][1] * 1LL * (comb(wek[1].size() - neigh[x][y][1], 2)) + res) % MOD; } // 1 1 2 2 if (DEBUG) printf("possibility 1 1 2 2\n"); add = 0; for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<indTwos[x][y];l++) { xa = x + dx[twos[x][y][l]]; ya = y + dy[twos[x][y][l]]; // A A for (l2=l+1;l2<indTwos[x][y];l2++) { xb = x + dx[twos[x][y][l2]]; yb = y + dy[twos[x][y][l2]]; minu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; minu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; minu++; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res = (res + (wek[1].size() - minu)) % MOD; } // AC C for (l2=0;l2<indTwos[xa][ya];l2++) { xb = xa + dx[twos[xa][ya][l2]]; yb = ya + dy[twos[xa][ya][l2]]; minu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; minu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; minu++; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res = (res + (wek[1].size() - minu)) % MOD; } // AC BC for (l2=0;l2<indTwos[xa][ya];l2++) { xb = xa + dx[twos[xa][ya][l2]]; yb = ya + dy[twos[xa][ya][l2]]; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && ii(x, y) < ii(xb + dx[l3], yb + dy[l3])) res++; } // AB AB if (x == xa && inRange(x + 1, y) && inRange(x + 1, ya)) { if (tab[x + 1][y] == 2 && tab[x + 1][ya] == 1) res++; } // AB A for (l2=0;l2<indTwos[x][y];l2++) if (l2 != l) { xb = x + dx[twos[x][y][l2]]; yb = y + dy[twos[x][y][l2]]; for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 1) xx[xa + dx[l3]][ya + dy[l3]] = 1; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 1) xx[xb + dx[l3]][yb + dy[l3]] = 0; for (l3=0;l3<4;l3++) { res += xx[xa + dx[l3]][ya + dy[l3]]; xx[xa + dx[l3]][ya + dy[l3]] = 0; } } // AB C for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && ii(x, y) < ii(xa + dx[l3], ya + dy[l3])) res += neigh[xa][ya][2]; // A B locSum = 0; for (l2=0;l2<4;l2++) { if (tab[xa + dx[l2]][ya + dy[l2]] == 2) xx[xa + dx[l2]][ya + dy[l2]] = 1; if (tab[x + dx[l2]][y + dy[l2]] == 2) xx[x + dx[l2]][y + dy[l2]] = 1; } for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 1) { xb = xa + dx[l2]; yb = ya + dy[l2]; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 2 && xx[xb + dx[l3]][yb + dy[l3]] == 0) locSum++; } for (l2=0;l2<4;l2++) { if (xx[xa + dx[l2]][ya + dy[l2]]) { locSum += neigh[xa + dx[l2]][ya + dy[l2]][1]; xx[xa + dx[l2]][ya + dy[l2]] = 0; } if (xx[x + dx[l2]][y + dy[l2]]) { locSum += neigh[x + dx[l2]][y + dy[l2]][1]; xx[x + dx[l2]][y + dy[l2]] = 0; } } add = add + sum - locSum; } } res = ((add / 2) + res) % MOD; // 1 1 2 3 if (DEBUG) printf("possibility 1 1 2 3\n"); for (i=0;i<wek[3].size();i++) { x = wek[3][i].first; y = wek[3][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][1], 2); res = (neigh[xa][ya][1] * 1LL * (wek[1].size() - neigh[xa][ya][1]) + res) % MOD; } } res %= MOD; // 1 2 2 2 if (DEBUG) printf("possibility 1 2 2 2\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; res += comb(neigh[x][y][2], 3); for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][2], 2); for (l2=l+1;l2<4;l2++) if (tab[x + dx[l2]][y + dy[l2]] == 2) { xb = x + dx[l2]; yb = y + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 2 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { plu++; xx[xa + dx[l3]][ya + dy[l3]] = 1; } if (tab[xb + dx[l3]][yb + dy[l3]] == 2 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { plu++; xx[xb + dx[l3]][yb + dy[l3]] = 1; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res += plu; } for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 2) { xb = xa + dx[l3]; yb = ya + dy[l3]; for (l4=0;l4<4;l4++) if (tab[xb + dx[l4]][yb + dy[l4]] == 2) { bOk = true; for (l5=0;l5<4;l5++) { if (x + dx[l5] == xb + dx[l4] && y + dy[l5] == yb + dy[l4]) { bOk = false; break; } if (xa + dx[l5] == xb + dx[l4] && ya + dy[l5] == yb + dy[l4]) { bOk = false; break; } } if (bOk) res++; } } } } res %= MOD; // 1 2 2 3 if (DEBUG) printf("possibility 1 2 2 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += neigh[xa][ya][2] * neigh[xa][ya][3]; for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 2) res += neigh[xa + dx[l2]][ya + dy[l2]][3]; for (l2=l+1;l2<4;l2++) if (tab[x + dx[l2]][y + dy[l2]] == 2) { xb = x + dx[l2]; yb = y + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 3 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; plu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 3 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; plu++; } } res += plu; for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; } for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) { xb = xa + dx[l2]; yb = ya + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 2) { xx[xb + dx[l3]][yb + dy[l3]] = 1; plu++; } for (l3=0;l3<4;l3++) if (tab[x + dx[l3]][y + dy[l3]] == 2 && xx[x + dx[l3]][y + dy[l3]] == 1) plu--; res += plu; for (l3=0;l3<4;l3++) xx[xb + dx[l3]][yb + dy[l3]] = 0; } } } res %= MOD; // 1 2 3 3 if (DEBUG) printf("possibility 1 2 3 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][3], 2); for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) { res += neigh[xa + dx[l2]][ya + dy[l2]][3]; } } } res %= MOD; // 1 2 3 4 if (DEBUG) printf("possibility 1 2 3 4\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) res += neigh[xa + dx[l2]][ya + dy[l2]][4]; } } res %= MOD; } res %= MOD; printf("%d\n", res); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | #include<cstdio> #include<iostream> #include<sstream> #include<cmath> #include<algorithm> #include<map> #include<set> #include<list> #include<vector> #include<stack> #include<queue> #include<string> #include<iomanip> #include<fstream> #include<ctime> #include<climits> using namespace std; typedef vector<int> VI; typedef pair <int,int> ii; typedef long long LL; #define pb push_back const int MOD = 1000000007; const int N = 3010; bool DEBUG = false; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; int tt[10], n, k, i, j, l, l1, l2, l3, l4, l5, x, y, xa, ya, xb, yb, res, sum, locSum, minu, plu; LL add; bool bOk; char tab[N][N], neigh[N][N][5]; char twos[N][N][4]; int indTwos[N][N]; char t[N]; bool xx[N][N]; vector<ii> wek[5]; set<ii>::iterator it, it2; bool inRange(int a, int b) { return a >= 1 && a <= n && b >= 1 && b <= n; } bool isOk(int a, int b) { return inRange(a, b) && tab[a][b] == -1; } void mark(int m) { int i, j, l; for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (tab[i][j] == m - 1) for (l=0;l<4;l++) if (isOk(i + dx[l], j + dy[l])) { tab[i + dx[l]][j + dy[l]] = m; wek[m].pb(ii(i + dx[l], j + dy[l])); } } void countNeigh() { int i, j, l; for (i=1;i<=n;i++) for (j=1;j<=n;j++) { for (l=0;l<=4;l++) neigh[i][j][l] = 0; indTwos[i][j] = 0; for (l=0;l<4;l++) { if (tab[i + dx[l]][j + dy[l]] != -1) neigh[i][j][tab[i + dx[l]][j + dy[l]]]++; if (tab[i + dx[l]][j + dy[l]] == 2) twos[i][j][indTwos[i][j]++] = l; } } } LL comb(int a, int b) { if (a < b) return 0; if (b == 0) return 1; if (b == 1) return a; int i, j; for (i=0;i<b;i++) tt[i] = a - i; for (j=b;j>=2;j--) { for (i=0;i<b;i++) if (tt[i] % j == 0) { tt[i] /= j; break; } } int res = 1; for (i=0;i<b;i++) res = (res * 1LL * tt[i]) % MOD; return res; } int main() { scanf("%d %d", &n, &k); for (i=0;i<=n+1;i++) for (j=0;j<=n+1;j++) tab[i][j] = -1; for (i=1;i<=n;i++) { scanf("%s", t); for (j=1;j<=n;j++) if (t[j - 1] == '#') tab[i][j] = 0; } for (i=1;i<=k;i++) { wek[i].clear(); mark(i); } /*if (DEBUG) { for (i=1;i<=n;i++) { for (j=1;j<=n;j++) if (tab[i][j]<0) printf("."); else if (tab[i][j]==0) printf("#"); else printf("%d", tab[i][j]); printf("\n"); } }*/ countNeigh(); res = 0; if (k == 1) { // 1 res += wek[1].size(); } else if (k == 2) { // 1 1 if (DEBUG) printf("possibility 1 1\n"); res = comb(wek[1].size(), 2); if (DEBUG) printf("%d\n", res); // 1 2 if (DEBUG) printf("possibility 1 2\n"); for (i=0;i<wek[1].size();i++) { res += neigh[wek[1][i].first][wek[1][i].second][2]; } res %= MOD; if (DEBUG) printf("%d\n", res); } else if (k == 3) { // 1 1 1 if (DEBUG) printf("possibility 1 1 1\n"); res = comb(wek[1].size(), 3); if (DEBUG) printf("%d\n", res); // 1 1 2 if (DEBUG) printf("possibility 1 1 2\n"); for (i=0;i<wek[2].size();i++) { x = wek[2][i].first; y = wek[2][i].second; res += comb(neigh[x][y][1], 2); res = (neigh[x][y][1] * 1LL * (wek[1].size() - neigh[x][y][1]) + res) % MOD; } if (DEBUG) printf("%d\n", res); // 1 2 2 if (DEBUG) printf("possibility 1 2 2\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; res += comb(neigh[x][y][2], 2); for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { res += neigh[x + dx[l]][y + dy[l]][2]; } } res %= MOD; if (DEBUG) printf("%d\n", res); // 1 2 3 if (DEBUG) printf("possibility 1 2 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { res += neigh[x + dx[l]][y + dy[l]][3]; } } res %= MOD; if (DEBUG) printf("%d\n", res); } else if (k == 4) { sum = 0; for (i=0;i<wek[2].size();i++) sum += neigh[wek[2][i].first][wek[2][i].second][1]; // 1 1 1 1 if (DEBUG) printf("possibility 1 1 1 1\n"); res = comb(wek[1].size(), 4); // 1 1 1 2 if (DEBUG) printf("possibility 1 1 1 2\n"); for (i=0;i<wek[2].size();i++) { x = wek[2][i].first; y = wek[2][i].second; res += comb(neigh[x][y][1], 3); res = (comb(neigh[x][y][1], 2) * 1LL * (wek[1].size() - neigh[x][y][1]) + res) % MOD; res = (neigh[x][y][1] * 1LL * (comb(wek[1].size() - neigh[x][y][1], 2)) + res) % MOD; } // 1 1 2 2 if (DEBUG) printf("possibility 1 1 2 2\n"); add = 0; for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<indTwos[x][y];l++) { xa = x + dx[twos[x][y][l]]; ya = y + dy[twos[x][y][l]]; // A A for (l2=l+1;l2<indTwos[x][y];l2++) { xb = x + dx[twos[x][y][l2]]; yb = y + dy[twos[x][y][l2]]; minu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; minu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; minu++; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res = (res + (wek[1].size() - minu)) % MOD; } // AC C for (l2=0;l2<indTwos[xa][ya];l2++) { xb = xa + dx[twos[xa][ya][l2]]; yb = ya + dy[twos[xa][ya][l2]]; minu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; minu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; minu++; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res = (res + (wek[1].size() - minu)) % MOD; } // AC BC for (l2=0;l2<indTwos[xa][ya];l2++) { xb = xa + dx[twos[xa][ya][l2]]; yb = ya + dy[twos[xa][ya][l2]]; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 1 && ii(x, y) < ii(xb + dx[l3], yb + dy[l3])) res++; } // AB AB if (x == xa && inRange(x + 1, y) && inRange(x + 1, ya)) { if (tab[x + 1][y] == 2 && tab[x + 1][ya] == 1) res++; } // AB A for (l2=0;l2<indTwos[x][y];l2++) if (l2 != l) { xb = x + dx[twos[x][y][l2]]; yb = y + dy[twos[x][y][l2]]; for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 1) xx[xa + dx[l3]][ya + dy[l3]] = 1; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 1) xx[xb + dx[l3]][yb + dy[l3]] = 0; for (l3=0;l3<4;l3++) { res += xx[xa + dx[l3]][ya + dy[l3]]; xx[xa + dx[l3]][ya + dy[l3]] = 0; } } // AB C for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 1 && ii(x, y) < ii(xa + dx[l3], ya + dy[l3])) res += neigh[xa][ya][2]; // A B locSum = 0; for (l2=0;l2<4;l2++) { if (tab[xa + dx[l2]][ya + dy[l2]] == 2) xx[xa + dx[l2]][ya + dy[l2]] = 1; if (tab[x + dx[l2]][y + dy[l2]] == 2) xx[x + dx[l2]][y + dy[l2]] = 1; } for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 1) { xb = xa + dx[l2]; yb = ya + dy[l2]; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 2 && xx[xb + dx[l3]][yb + dy[l3]] == 0) locSum++; } for (l2=0;l2<4;l2++) { if (xx[xa + dx[l2]][ya + dy[l2]]) { locSum += neigh[xa + dx[l2]][ya + dy[l2]][1]; xx[xa + dx[l2]][ya + dy[l2]] = 0; } if (xx[x + dx[l2]][y + dy[l2]]) { locSum += neigh[x + dx[l2]][y + dy[l2]][1]; xx[x + dx[l2]][y + dy[l2]] = 0; } } add = add + sum - locSum; } } res = ((add / 2) + res) % MOD; // 1 1 2 3 if (DEBUG) printf("possibility 1 1 2 3\n"); for (i=0;i<wek[3].size();i++) { x = wek[3][i].first; y = wek[3][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][1], 2); res = (neigh[xa][ya][1] * 1LL * (wek[1].size() - neigh[xa][ya][1]) + res) % MOD; } } res %= MOD; // 1 2 2 2 if (DEBUG) printf("possibility 1 2 2 2\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; res += comb(neigh[x][y][2], 3); for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][2], 2); for (l2=l+1;l2<4;l2++) if (tab[x + dx[l2]][y + dy[l2]] == 2) { xb = x + dx[l2]; yb = y + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 2 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { plu++; xx[xa + dx[l3]][ya + dy[l3]] = 1; } if (tab[xb + dx[l3]][yb + dy[l3]] == 2 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { plu++; xx[xb + dx[l3]][yb + dy[l3]] = 1; } } for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; res += plu; } for (l3=0;l3<4;l3++) if (tab[xa + dx[l3]][ya + dy[l3]] == 2) { xb = xa + dx[l3]; yb = ya + dy[l3]; for (l4=0;l4<4;l4++) if (tab[xb + dx[l4]][yb + dy[l4]] == 2) { bOk = true; for (l5=0;l5<4;l5++) { if (x + dx[l5] == xb + dx[l4] && y + dy[l5] == yb + dy[l4]) { bOk = false; break; } if (xa + dx[l5] == xb + dx[l4] && ya + dy[l5] == yb + dy[l4]) { bOk = false; break; } } if (bOk) res++; } } } } res %= MOD; // 1 2 2 3 if (DEBUG) printf("possibility 1 2 2 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += neigh[xa][ya][2] * neigh[xa][ya][3]; for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 2) res += neigh[xa + dx[l2]][ya + dy[l2]][3]; for (l2=l+1;l2<4;l2++) if (tab[x + dx[l2]][y + dy[l2]] == 2) { xb = x + dx[l2]; yb = y + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) { if (tab[xa + dx[l3]][ya + dy[l3]] == 3 && xx[xa + dx[l3]][ya + dy[l3]] == 0) { xx[xa + dx[l3]][ya + dy[l3]] = 1; plu++; } if (tab[xb + dx[l3]][yb + dy[l3]] == 3 && xx[xb + dx[l3]][yb + dy[l3]] == 0) { xx[xb + dx[l3]][yb + dy[l3]] = 1; plu++; } } res += plu; for (l3=0;l3<4;l3++) xx[xa + dx[l3]][ya + dy[l3]] = xx[xb + dx[l3]][yb + dy[l3]] = 0; } for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) { xb = xa + dx[l2]; yb = ya + dy[l2]; plu = 0; for (l3=0;l3<4;l3++) if (tab[xb + dx[l3]][yb + dy[l3]] == 2) { xx[xb + dx[l3]][yb + dy[l3]] = 1; plu++; } for (l3=0;l3<4;l3++) if (tab[x + dx[l3]][y + dy[l3]] == 2 && xx[x + dx[l3]][y + dy[l3]] == 1) plu--; res += plu; for (l3=0;l3<4;l3++) xx[xb + dx[l3]][yb + dy[l3]] = 0; } } } res %= MOD; // 1 2 3 3 if (DEBUG) printf("possibility 1 2 3 3\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; res += comb(neigh[xa][ya][3], 2); for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) { res += neigh[xa + dx[l2]][ya + dy[l2]][3]; } } } res %= MOD; // 1 2 3 4 if (DEBUG) printf("possibility 1 2 3 4\n"); for (i=0;i<wek[1].size();i++) { x = wek[1][i].first; y = wek[1][i].second; for (l=0;l<4;l++) if (tab[x + dx[l]][y + dy[l]] == 2) { xa = x + dx[l]; ya = y + dy[l]; for (l2=0;l2<4;l2++) if (tab[xa + dx[l2]][ya + dy[l2]] == 3) res += neigh[xa + dx[l2]][ya + dy[l2]][4]; } } res %= MOD; } res %= MOD; printf("%d\n", res); } |