Submission #1125942

#TimeUsernameProblemLanguageResultExecution timeMemory
1125942patgraSnake Escaping (JOI18_snake_escaping)C++20
75 / 100
2072 ms26060 KiB
#include <bits/stdc++.h>

#define rep(a,b,c) for(auto a = (b); a != (c); a++)
#define repD(a,b,c) for(auto a = (b); a != (c); a--)
#define repIn(a, b) for(auto& a : (b))
#define repIn2(a, b, c) for(auto& [a, b] : c)

#define ll long long

constexpr bool dbg = false;
#define DEBUG if constexpr(dbg)
#define DC DEBUG std::cerr
#define eol std::endl

using namespace std;

constexpr int maxl = 20, maxn = 1 << maxl, xd = 6;
int l, q;
int arr[maxn], sosTmp1[maxn], sosTmp2[maxn], sosDown[maxn], sosUp[maxn];
string str;

void input() {
    scanf("%d%d", &l, &q);
    rep(i, 0, 1 << l) scanf(" %c", arr + i), arr[i] -= '0';
}

void preprocess() {
    rep(i, 0, 1 << l) sosTmp2[i] = arr[i];
    rep(i, 1, l + 1) {
        swap(sosTmp1, sosTmp2);
        rep(mask, 0, 1 << l) sosTmp2[mask] = sosTmp1[mask] + ((mask & (1 << (i - 1))) ? (sosTmp1[mask ^ (1 << (i - 1))]) : 0);
    }
    swap(sosTmp2, sosDown);
    rep(i, 0, 1 << l) sosTmp2[i] = arr[i];
    rep(i, 1, l + 1) {
        swap(sosTmp1, sosTmp2);
        rep(mask, 0, 1 << l) sosTmp2[mask] = sosTmp1[mask] + ((mask & (1 << (i - 1))) ? 0 : (sosTmp1[mask ^ (1 << (i - 1))]));
    }
    swap(sosTmp2, sosUp);
    DEBUG {
        DC << "SOS DOWN: " << eol;
        rep(i, 0, l + 1) { DC << ' '; rep(mask, 0, 1 << l) DC << sosDown[mask] << ' '; DC << eol;}
        DC << "SOS UP: " << eol;
        rep(i, 0, l + 1) { DC << ' '; rep(mask, 0, 1 << l) DC << sosUp[mask] << ' '; DC << eol;}
    }
}

ll pala1() {
    vector<int> questionMarks;
    int mask = 0;
    ll ans = 0;
    rep(i, 0, l) {
        if (str[i] == '?') questionMarks.push_back(i);
        else mask |= (str[i] - '0') << i;
    }
    rep(i, 0, 1 << questionMarks.size()) {
        rep(j, 0, questionMarks.size()) if (i & (1 << j)) mask |= 1 << questionMarks[j];
        ans += arr[mask];
        rep(j, 0, questionMarks.size()) if (i & (1 << j)) mask ^= 1 << questionMarks[j];
    }
    return ans;
}

ll pala2() {
    DC << "Query " << str << ":" << eol;
    vector<int> ones;
    int mask = 0;
    rep(i, 0, l) {
        if (str[i] == '1') ones.push_back(i), mask |= 1 << i;
        if (str[i] == '?') mask |= 1 << i;
    }
    ll ans = 0;
    DC << " ones: "; DEBUG repIn(i, ones) DC << i << ' '; DC << eol;
    rep(maskOnes, 0, 1 << ones.size()) {
        rep(i, 0, ones.size()) if (maskOnes & (1 << i)) mask ^= 1 << ones[i];
        ans += sosDown[mask] * (__builtin_popcount(maskOnes) % 2 == 0 ? 1 : -1);
        DC << " Adding " << sosDown[mask] * (__builtin_popcount(maskOnes) % 2 == 0 ? 1 : -1) << " for mask " << mask << eol;
        rep(i, 0, ones.size()) if (maskOnes & (1 << i)) mask ^= 1 << ones[i];
    }
    return ans;
}

ll pala3() {
    vector<int> zeros;
    int mask = 0;
    rep(i, 0, l) {
        if (str[i] == '0') zeros.push_back(i);
        if (str[i] == '1') mask |= 1 << i;
    }
    ll ans = 0;
    rep(maskZeros, 0, 1 << zeros.size()) {
        rep(i, 0, zeros.size()) if (maskZeros & (1 << i)) mask ^= 1 << zeros[i];
        ans += sosUp[mask] * (__builtin_popcount(maskZeros) % 2 == 0 ? 1 : -1);
        rep(i, 0, zeros.size()) if (maskZeros & (1 << i)) mask ^= 1 << zeros[i];
    }
    return ans;
}

void processQueries() {
    str.resize(l);
    rep(i, 0, q) {
        rep(j, 0, l) scanf(" %c", &str[l - j - 1]);
        int cnt1 = 0, cnt0 = 0, cntQ = 0;
        repIn(c, str) (c == '1' ? cnt1 : c == '0' ? cnt0 : cntQ)++;
        // printf("%lld\n", pala3());
        // continue;
        if (cntQ <= xd) printf("%lld\n", pala1());
        else if (cnt1 <= xd) printf("%lld\n", pala2());
        else if (cnt0 <= xd) printf("%lld\n", pala3());
    }
}

int main() {
    input();
    preprocess();
    processQueries();
    return 0;
}

Compilation message (stderr)

snake_escaping.cpp: In function 'void input()':
snake_escaping.cpp:24:32: warning: format '%c' expects argument of type 'char*', but argument 2 has type 'int*' [-Wformat=]
   24 |     rep(i, 0, 1 << l) scanf(" %c", arr + i), arr[i] -= '0';
      |                               ~^   ~~~~~~~
      |                                |       |
      |                                char*   int*
      |                               %d
snake_escaping.cpp:23:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   23 |     scanf("%d%d", &l, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~
snake_escaping.cpp:24:28: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   24 |     rep(i, 0, 1 << l) scanf(" %c", arr + i), arr[i] -= '0';
      |                       ~~~~~^~~~~~~~~~~~~~~~
snake_escaping.cpp: In function 'void processQueries()':
snake_escaping.cpp:102:27: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |         rep(j, 0, l) scanf(" %c", &str[l - j - 1]);
      |                      ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...