QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#328843 | #5853. The Paths of Yin Yang | hos_lyric | 17 | 86ms | 4164kb | C++14 | 6.6kb | 2024-02-16 08:44:34 | 2024-02-16 08:44:34 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
constexpr int LIM = 105;
int cache[LIM][LIM];
int uf[LIM * LIM];
int root(int u) {
return (uf[u] < 0) ? u : (uf[u] = root(uf[u]));
}
bool connect(int u, int v) {
u = root(u);
v = root(v);
if (u == v) return false;
if (uf[u] > uf[v]) swap(u, v);
uf[u] += uf[v];
uf[v] = u;
return true;
}
int qsLen[2];
pair<int, int> qs[2][4 * LIM];
__int128 board[LIM];
int main() {
for (int m = 0; m < LIM; ++m) for (int n = 0; n < LIM; ++n) {
cache[m][n] = -1;
}
int numCases;
scanf("%d", &numCases);
for (int caseId = 1; caseId <= numCases; ++caseId) {
cerr << "==== Case #" << caseId << " ====" << endl;
int M, N;
scanf("%d%d", &M, &N);
if (M > N) {
swap(M, N);
}
if (cache[M][N] == -1) {
int ans = 0;
vector<pair<int, int>> ps;
for (int y = 1; y < N; ++y) ps.emplace_back(1, y);
for (int x = 1; x < M; ++x) ps.emplace_back(x, N);
for (int y = N; y > 1; --y) ps.emplace_back(M, y);
for (int x = M; x > 1; --x) ps.emplace_back(x, 1);
const int psLen = ps.size();
for (int i = 1; i <= psLen; ++i) for (int j = i + 1; j <= psLen; ++j) {
vector<pair<int, int>> qsF[2], qsB[2];
for (int k = 0; k < psLen; ++k) {
if (((ps[k].first == 1 || ps[k].first == M) && (ps[k].second == 1 || ps[k].second == N)) ||
k == j % psLen || k == i - 1 || k == i || k == j - 1) {
for (int d = -M; d <= +M; ++d) {
const int s = ((i <= k && k < j) ? 1 : 0) ^ (d & 1);
{
const int xx = ps[k].first + d;
const int yy = ps[k].second + d;
if (1 <= xx && xx <= M && 1 <= yy && yy <= N) {
qsF[s].emplace_back(xx, yy);
}
}
{
const int xx = ps[k].first + d;
const int yy = ps[k].second - d;
if (1 <= xx && xx <= M && 1 <= yy && yy <= N) {
qsB[s].emplace_back(xx, yy);
}
}
}
}
}
for (int s = 0; s < 2; ++s) {
sort(qsF[s].begin(), qsF[s].end());
sort(qsB[s].begin(), qsB[s].end());
qsF[s].erase(unique(qsF[s].begin(), qsF[s].end()), qsF[s].end());
qsB[s].erase(unique(qsB[s].begin(), qsB[s].end()), qsB[s].end());
qsLen[s] = set_intersection(qsF[s].begin(), qsF[s].end(), qsB[s].begin(), qsB[s].end(), qs[s]) - qs[s];
}
board[1] = 0;
for (int k = 0; k < N; ++k) {
if (i <= k && k < j) {
board[1] |= (__int128)1 << (1 + k);
}
}
board[1] |= ((board[1] >> 1) & 1) ^ 1;
board[1] |= (((board[1] >> N) & 1) ^ 1) << (N + 1);
board[0] = board[1] ^ (((__int128)1 << (N + 2)) - 1);
for (int l00 = 0; l00 < qsLen[0]; ++l00) for (int l01 = l00 + 1; l01 < qsLen[0]; ++l01)
for (int l10 = 0; l10 < qsLen[1]; ++l10) for (int l11 = l10 + 1; l11 < qsLen[1]; ++l11)
{
for (int x = 1; x <= M; ++x) {
const __int128 bU = board[x - 1];
const __int128 bL = board[x] << 1;
const __int128 bR = board[x] >> 1;
board[x + 1] = (bU ^ bL ^ bR) & (((__int128)1 << (N + 1)) - 2);
if (qs[0][l00].first == x) {
if (board[x] & (__int128)1 << qs[0][l00].second) goto failed;
board[x + 1] ^= (__int128)1 << qs[0][l00].second;
}
if (qs[0][l01].first == x) {
if (board[x] & (__int128)1 << qs[0][l01].second) goto failed;
board[x + 1] ^= (__int128)1 << qs[0][l01].second;
}
if (qs[1][l10].first == x) {
if (!(board[x] & (__int128)1 << qs[1][l10].second)) goto failed;
board[x + 1] ^= (__int128)1 << qs[1][l10].second;
}
if (qs[1][l11].first == x) {
if (!(board[x] & (__int128)1 << qs[1][l11].second)) goto failed;
board[x + 1] ^= (__int128)1 << qs[1][l11].second;
}
if (bU & bL & bR & board[x + 1]) {
goto failed;
}
if (~(bU | bL | bR | board[x + 1]) & (((__int128)1 << (N + 1)) - 2)) {
goto failed;
}
board[x + 1] |= ((board[x + 1] >> 1) & 1) ^ 1;
board[x + 1] |= (((board[x + 1] >> N) & 1) ^ 1) << (N + 1);
}
if ((board[M] ^ (((__int128)1 << (N + 2)) - 1)) != board[M + 1]) {
goto failed;
}
for (int k = 0; k < psLen; ++k) {
if ((bool)(board[ps[k].first] & (__int128)1 << ps[k].second) != (i <= k && k < j)) {
goto failed;
}
}
fill(uf, uf + M * N, -1);
for (int x = 1; x <= M; ++x) for (int y = 1; y <= N; ++y) {
if (x > 1 && (bool)(board[x - 1] & (__int128)1 << y) == (bool)(board[x] & (__int128)1 << y)) {
if (!connect((x - 1 - 1) * N + (y - 1), (x - 1) * N + (y - 1))) {
goto failed;
}
}
if (y > 1 && (bool)(board[x] & (__int128)1 << (y - 1)) == (bool)(board[x] & (__int128)1 << y)) {
if (!connect((x - 1) * N + (y - 1 - 1), (x - 1) * N + (y - 1))) {
goto failed;
}
}
}
++ans;
// cout<<"solution"<<endl;for(int x=1;x<=M;++x){for(int y=1;y<=N;++y){cout<<(int)((board[x]>>y)&1);}cout<<endl;}
failed:{}
}
}
ans *= 2;
cache[M][N] = ans;
}
printf("Case #%d: %d\n", caseId, cache[M][N]);
fflush(stdout);
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 17
Accepted
Test #1:
score: 17
Accepted
time: 86ms
memory: 4164kb
input:
50 4 8 7 8 10 7 6 4 5 5 4 10 8 9 5 6 7 5 6 8 7 10 10 6 9 4 5 4 7 4 9 7 4 6 6 9 4 5 7 6 9 5 6 6 5 9 5 10 8 7 4 9 4 4 10 9 10 5 9 8 8 6 8 4 8 10 6 5 6 9 8 8 10 4 6 7 5 8 7 7 10 8 9 6 7 9 4 7 5 7 6 10 9 10 10 10 9 9 8 5
output:
Case #1: 40 Case #2: 144 Case #3: 168 Case #4: 44 Case #5: 48 Case #6: 36 Case #7: 168 Case #8: 76 Case #9: 88 Case #10: 112 Case #11: 168 Case #12: 128 Case #13: 36 Case #14: 44 Case #15: 36 Case #16: 168 Case #17: 44 Case #18: 116 Case #19: 44 Case #20: 116 Case #21: 88 Case #22: 72 Case #23: 88 C...
result:
ok 50 lines
Subtask #2:
score: 0
Time Limit Exceeded
Test #2:
score: 0
Time Limit Exceeded
input:
50 94 100 38 9 6 8 14 46 6 46 9 50 19 47 23 16 43 9 17 30 10 49 35 20 24 24 38 41 25 11 100 100 37 11 8 45 33 99 70 69 35 69 37 35 47 21 22 23 10 47 40 8 100 51 23 10 47 40 70 13 6 37 24 16 47 43 32 21 99 95 34 43 70 4 5 69 21 32 8 23 41 35 33 16 13 45 25 14 34 42 8 25 37 34 24 15 9 32 26 41
output:
Case #1: 36132 Case #2: 540 Case #3: 112 Case #4: 756 Case #5: 108 Case #6: 684 Case #7: 1840 Case #8: 736 Case #9: 600 Case #10: 1116 Case #11: 360 Case #12: 864 Case #13: 576 Case #14: 6236 Case #15: 568 Case #16: 12000 Case #17: 808 Case #18: 144 Case #19: 5456