Submission #718886

#TimeUsernameProblemLanguageResultExecution timeMemory
718886edenoooWeird Numeral System (CCO21_day1problem2)C++17
8 / 25
38 ms27880 KiB
#include<bits/stdc++.h> using namespace std; #define INF 1234567890 #define ll long long #define SZ 60 bool rev; ll N; int K, Q, D, M; int A[5001], n[SZ]; bool suf[SZ+1]; vector<int> X[1000000]; vector<pair<int, int> > Y[10001]; int dp[SZ][10001], DP[10001]; pair<int, int> P[10001]; int f(int i, int j) { assert(abs(j) <= 5000); if (i >= SZ) return DP[j+5000]; if (i > 0 && suf[i] && j == 0) return true; int &ret = dp[i][j+5000]; if (ret != -1) return ret; ret = 0; // j+x = n[i] (mod K)인 x를 사용해야 한다. for(int x : X[((n[i]-j)%K+K)%K]) if (f(i+1, (j+x-n[i] >= 0 ? (j+x-n[i])/K : -((-(j+x-n[i])+K-1)/K)))) { ret = 1; break; } return ret; } void G(int j) { assert(abs(j) <= 5000); if (j == 0) return; auto [nj,x] = P[j+5000]; G(nj); cout << (rev ? -x : x) << " "; } void g(int i, int j) { if (i >= SZ) { G(j); return; } if (i > 0 && suf[i] && j == 0) return; for(int x : X[((n[i]-j)%K+K)%K]) if (f(i+1, (j+x-n[i] >= 0 ? (j+x-n[i])/K : -((-(j+x-n[i])+K-1)/K)))) { g(i+1, (j+x-n[i] >= 0 ? (j+x-n[i])/K : -((-(j+x-n[i])+K-1)/K))); cout << (rev ? -x : x) << " \n"[i==0]; return; } } int main() { ios::sync_with_stdio(0); cin.tie(0); cin.exceptions(ios::badbit | ios::failbit); cin >> K >> Q >> D >> M; for(int i=1; i<=D; i++) { cin >> A[i]; } while(Q--) { // clear rev = false; for(int i=0; i<1000000; i++) X[i].clear(); for(int i=0; i<10001; i++) Y[i].clear(); memset(dp, -1, sizeof(dp)); memset(DP, 0, sizeof(DP)); cin >> N; if (N < 0) { rev = true; N = -N; for(int i=1; i<=D; i++) A[i] = -A[i]; } for(int i=0; i<SZ; i++) { n[i] = N % K; N /= K; } suf[SZ] = true; for(int i=SZ-1; i>=0; i--) suf[i] = suf[i+1] && (n[i] == 0); for(int i=1; i<=D; i++) X[(A[i]%K+K)%K].push_back(A[i]); // 길이가 매우 길 수 있나? i >= 60에서는 BFS를 돌려 주자. // 전이 방향이 반대라서 그래프를 새로 만들어야 한다... for(int j=-5000; j<=5000; j++) for(int x : X[((0-j)%K+K)%K]) { int nj = (j+x >= 0 ? (j+x)/K : -((-(j+x)+K-1)/K)); Y[nj+5000].push_back({j, x}); // j에서 x를 사용하면 nj로 갈 수 있다. } queue<int> q; q.push(0), DP[0+5000] = 1; while(!q.empty()) { int j = q.front(); q.pop(); for(auto [pj,x] : Y[j+5000]) // j로 올 수 있는 애들 { if (DP[pj+5000]) continue; q.push(pj), DP[pj+5000] = 1, P[pj+5000] = {j, x}; } } if (!f(0, 0)) cout << "IMPOSSIBLE\n"; else g(0, 0); // 역추적 if (rev) for(int i=1; i<=D; i++) A[i] = -A[i]; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...