#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); } |
English