二進位制的世界 題解
阿新 • • 發佈:2022-04-12
Solution
考慮直接值域分塊,那我們可以設 \(f(u,v)\) 表示你選的 \(a_j\) 前 \(8\) 位為 \(u\),如果 \(a_u\) 後面 \(8\) 位為 \(v\) 的答案,不難看出,我們可以 \(n\sqrt V\) 直接維護。
感覺這種做法還是挺具有普遍性的。
Code
#include <bits/stdc++.h> using namespace std; #define Int register int #define MAXN template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;} template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);} template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} template <typename T> inline void chkmax (T &a,T b){a = max (a,b);} template <typename T> inline void chkmin (T &a,T b){a = min (a,b);} int n; struct node{ int v,tot; node operator + (const node &p)const{ if (v > p.v) return *this; else if (v == p.v) return node{v,tot + p.tot}; else return p; } }; char str[5]; node f[1 << 8][1 << 8]; node queryit (int vnow,int type){ int L = vnow >> 8,R = vnow ^ (L << 8);node ans = node{0,0}; for (Int v = 0;v < (1 << 8);++ v){ int vs = (type == 1 ? (L & v) : (type == 2 ? (L | v) : (L ^ v))); // cout << v << ": " << (vs << 8) << " , " << f[v][R].v << " & " << f[v][R].tot << endl; if (f[v][R].tot) ans = ans + node{(vs << 8) + f[v][R].v,f[v][R].tot}; } return ans; } void change (int vnow,int type){ int L = vnow >> 8,R = vnow ^ (L << 8); for (Int v = 0;v < (1 << 8);++ v){ int vs = (type == 1 ? (R & v) : (type == 2 ? (R | v) : (R ^ v))); if (f[L][v].tot) f[L][v] = f[L][v] + node{vs,1}; else f[L][v] = node{vs,1}; } } signed main(){ // freopen ("data1.in","r",stdin); // freopen ("f1.out","w",stdout); read (n),scanf ("%s",str + 1);int typ = str[1] == 'a' ? 1 : (str[1] == 'o' ? 2 : 3); for (Int i = 1;i <= n;++ i){ int vnow;read (vnow); if (i != 1){ node it = queryit (vnow,typ); write (it.v),putchar (' '),write (it.tot),putchar ('\n'); } change (vnow,typ); } return 0; } /* 2 or 3449 21268 */