Submission #56588

#TimeUsernameProblemLanguageResultExecution timeMemory
56588XellosSnake Escaping (JOI18_snake_escaping)C++14
12 / 100
891 ms66560 KiB
#pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include <bits/stdc++.h> // iostream is too mainstream #include <cstdio> // bitch please #include <iostream> #include <algorithm> #include <cstdlib> #include <vector> #include <set> #include <map> #include <queue> #include <stack> #include <list> #include <cmath> #include <iomanip> #include <time.h> #define dibs reserve #define OVER9000 1234567890123456789LL #define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++) #define tisic 47 #define soclose 1e-8 #define chocolate win // so much chocolate #define patkan 9 #define ff first #define ss second #define abs(x) ((x < 0)?-(x):x) #define uint unsigned int #define dbl long double #define pi 3.14159265358979323846 using namespace std; // mylittledoge typedef long long cat; #ifdef DONLINE_JUDGE // palindromic tree is better than splay tree! #define lld I64d #endif int cost_arr[2][1<<19]; int cost[1<<20]; int ans[1000000]; cat query[1000000]; void solve(int d, int B, int cl, int cr, int ql, int qr) { if(ql == qr) return; if(d == B-8) { vector<int> v(3*3*3*3*3*3*3*3, 0); for(int i = 0; i < 3*3*3*3*3*3*3*3; i++) { int x = i, y = 0, pw3 = 1; for(int j = 0; j <= 8; j++) { if(j == 8) { v[i] = cost[cl+y]; break; } if(x%3 == 2) { v[i] = v[i-pw3]+v[i-2*pw3]; break; } y += (1<<j) * (x%3); x /= 3; pw3 *= 3; } } for(int i = ql; i < qr; i++) { int w = 0; for(int j = 7; j >= 0; j--) { if((query[i]>>(20+d+j))&1) w = 3 * w + ((query[i]>>(d+j))&1); else w = 3 * w + 2; } ans[(query[i]>>40)&((1LL<<20)-1)] += ((query[i]>>60) ? -v[w] : v[w]); } return; } if(d == B) { for(int i = ql; i < qr; i++) ans[(query[i]>>40)&((1LL<<20)-1)] += ((query[i]>>60) ? -cost[cl] : cost[cl]); return; } int cnt[3] = {}; for(int i = ql; i < qr; i++) { if((query[i]>>(20+d))&1) cnt[(query[i]>>(d))&1]++; else cnt[2]++; } if(cnt[2] <= cnt[0] && cnt[2] <= cnt[1]) { for(int i = 0; i < (1<<(B-1-d)); i++) { cost_arr[0][i] = cost[cl+2*i]; cost_arr[1][i] = cost[cl+2*i+1]; } for(int i = 0; i < (1<<(B-1-d)); i++) cost[cl+i] = cost_arr[0][i]; for(int i = 0; i < (1<<(B-1-d)); i++) cost[cl+(1<<(B-1-d))+i] = cost_arr[1][i]; int a = ql, b = ql+cnt[0]+cnt[2]; cat bits = (1LL<<(20+d)) + (1LL<<(d)); for(int i = ql; i < ql+cnt[0]+cnt[2]; i++) { if((query[i]>>(20+d))&1) { if((query[i]>>(d))&1) { for(; b < qr && (query[b]&bits) == bits; b++) {} if(b == qr) break; swap(query[i], query[b]); b++; } else { while(a < i && ((query[a]>>(20+d))&1) == 1 && ((query[a]>>(d))&1) == 0) a++; if(a == i) continue; swap(query[i], query[a]); a++; } } } solve(d+1, B, cl, cl+(1<<(B-1-d)), ql, ql+cnt[0]+cnt[2]); a = ql; for(int i = ql+cnt[0]; i < ql+cnt[0]+cnt[2]; i++) if(((query[i]>>(20+d))&1) == 1) { for(; a < ql+cnt[0] && ((query[a]>>(20+d))&1) == 1; a++) {} if(a == ql+cnt[0]) break; swap(query[i], query[a]); a++; } solve(d+1, B, cl+(1<<(B-1-d)), cr, qr-cnt[2]-cnt[1], qr); return; } int x = (int) (cnt[1] < cnt[0]); for(int i = 0; i < (1<<(B-1-d)); i++) { cost_arr[0][i] = cost[cl+2*i+1-x]; cost_arr[1][i] = cost[cl+2*i] + cost[cl+2*i+1]; } for(int i = 0; i < (1<<(B-1-d)); i++) cost[cl+i] = cost_arr[0][i]; for(int i = 0; i < (1<<(B-1-d)); i++) cost[cl+(1<<(B-1-d))+i] = cost_arr[1][i]; int a = ql, b = ql+cnt[1-x]+cnt[x]; for(int i = ql; i < ql+cnt[1-x]+cnt[x]; i++) { if((query[i]>>(20+d))&1) { if(((query[i]>>(d))&1) != x) { while(a < i && ((query[a]>>(20+d))&1) == 1 && ((query[a]>>(d))&1) != x) a++; if(a == i) continue; swap(query[i], query[a]); a++; } } else { while(b < qr && ((query[b]>>(20+d))&1) == 0) b++; swap(query[i], query[b]); b++; i--; } } for(int i = ql+cnt[1-x]; i < ql+cnt[1-x]+cnt[x]; i++) query[i] ^= 1LL<<60; solve(d+1, B, cl, cl+(1<<(B-1-d)), ql, ql+cnt[1-x]+cnt[x]); a = ql+cnt[1-x]; cat bits = (1LL<<(20+d)) + (1LL<<(d)); cat expect = (1LL<<(20+d)) + x * (1LL<<(d)); for(int i = ql; i < ql+cnt[1-x]; i++) if((query[i]&bits) == expect) { while(a < ql+cnt[1-x]+cnt[x] && (query[a]&bits) == expect) a++; if(a == ql+cnt[1-x]+cnt[x]) break; swap(query[i], query[a]); a++; } for(int i = ql+cnt[1-x]; i < ql+cnt[1-x]+cnt[x]; i++) query[i] ^= 1LL<<60; solve(d+1, B, cl+(1<<(B-1-d)), cr, qr-cnt[2]-cnt[x], qr); } int main() { cin.sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(10); int B, Q; char buf[(1<<20) + 10]; scanf("%d %d %s", &B, &Q, buf); for(int i = 0; i < (1<<B); i++) { int b = 0; for(int j = 0; j < B; j++) b = 2*b + ((i>>j)&1); cost[b] = buf[i]-'0'; } // query: mask, bits, id char buf_small[30]; for(int i = 0; i < Q; i++) { scanf("%s", buf_small); query[i] = (1LL*i)<<40; for(int j = 0; j < B; j++) { if(buf_small[j] == '?') continue; query[i] += 1LL<<(j+20); if(buf_small[j] == '1') query[i] += 1LL<<(j+0); } } memset(ans, 0, sizeof(ans)); solve(0, B, 0, 1<<B, 0, Q); for(int i = 0; i < Q; i++) cout << ans[i] << "\n"; return 0;} // look at my code // my code is amazing

Compilation message (stderr)

snake_escaping.cpp: In function 'int main()':
snake_escaping.cpp:169:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d %s", &B, &Q, buf);
  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
snake_escaping.cpp:178:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%s", buf_small);
   ~~~~~^~~~~~~~~~~~~~~~~
#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...