LOJ#6499. 「雅禮集訓 2018 Day2」顏色 題解
阿新 • • 發佈:2020-09-08
考慮分塊,設塊大小為\(S\)。每個塊用一個bitset記錄塊中顏色,整塊之間打st表,查詢的時候整塊st表查,零散部分暴力即可。
時間複雜度\(\Theta(\frac{nS\log S}{w}) - \Theta(\frac{n}{w}+S)\)
空間複雜度\(\Theta(n+\frac{nS\log S}{w})\)
code :
#include <bits/stdc++.h> #define LL unsigned long long using namespace std; template <typename T> void read(T &x){ static char ch; x = 0,ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) x = x * 10 + ch - '0',ch = getchar(); } inline void write(int x){if (x > 9) write(x/10); putchar(x%10+'0'); } const int N = 100005,L = 80; struct Bitst{ LL B[1563]; inline void ins(int p){ B[p>>6] |= 1ull << (p&63); } inline void Or(Bitst &A){ register int i = 0; for (; i < 1563; i += 16){ B[i] |= A.B[i], B[i+1] |= A.B[i+1], B[i+2] |= A.B[i+2], B[i+3] |= A.B[i+3], B[i+4] |= A.B[i+4], B[i+5] |= A.B[i+5], B[i+6] |= A.B[i+6], B[i+7] |= A.B[i+7], B[i+8] |= A.B[i+8], B[i+9] |= A.B[i+9], B[i+10] |= A.B[i+10], B[i+11] |= A.B[i+11], B[i+12] |= A.B[i+12], B[i+13] |= A.B[i+13], B[i+14] |= A.B[i+14], B[i+15] |= A.B[i+15]; } for (; i < 1563; ++i) B[i] |= A.B[i]; } }st[L+1][7],now; int Log[L+50]; inline void work(int l,int r){ if (l == r){ now.Or(st[l][0]); return; } static int t; t = Log[r-l+1]; if (r-l+1 == (1<<t+1) && t+1<7){ now.Or(st[l][t+1]); return; } now.Or(st[l][t]),now.Or(st[r-(1<<t)+1][t]); } int n,a[N],siz; inline int Cur(int i){ return (i-1)/siz+1; } inline int Left(int c){ return (c-1)*siz+1; } inline int Right(int c){ return min(n,c*siz); } int S[1<<16]; inline void initS(){ for (int i = 0; i < 1<<16; ++i) S[i] = S[i>>1] + (i&1); } inline int Count(LL x){ static int ret; ret = 0; while (x) ret += S[x&65535],x >>= 16; return ret; } int main(){ register int i,j; int q,type; read(n),read(q),read(type); for (i = 1; i <= n; ++i) read(a[i]),--a[i]; siz = max(1,n/L + (n%L?1:0)); for (i = 1; i <= L && Left(i) <= n; ++i) for (j = Left(i); j <= Right(i); ++j) st[i][0].ins(a[j]); for (i = 1; i <= L+10; ++i){ Log[i] = Log[i-1]; while ((1<<Log[i]+1) < i) ++Log[i]; } for (j = 1; j <= Log[L]; ++j) for (i = 1; i+(1<<j)-1 <= L; ++i){ memcpy(st[i][j].B,st[i][j-1].B,12504); st[i][j].Or(st[i+(1<<j-1)][j-1]); } int ans = 0,k,l,r,cl,cr,ll; bool First = 1; initS(); while (q--){ read(k),memset(now.B,0,12504); while (k--){ read(l),read(r); if (!First && type){ l ^= ans,r ^= ans,l = l % n + 1,r = r % n + 1; if (l > r) swap(l,r); } cl = Cur(l),cr = Cur(r); if (cl + 1 >= cr) for (i = l; i <= r; ++i) now.ins(a[i]); else{ work(cl+1,cr-1); for (i = l,ll = Right(cl); i <= ll; ++i) now.ins(a[i]); for (i = r,ll = Left(cr); i >= ll; --i) now.ins(a[i]); } } ans = 0; for (i = 0; i < 1563; ++i) if (now.B[i]) ans += Count(now.B[i]); write(ans),putchar('\n'); First = 0; } return 0; }