题意:
m维偏序问题。
解法:
考虑对每一维按照每一个元素在这一维的数值分块,对于每一个块维护一个大小为 n 的bitset,表示前缀/后缀满足条件的元素集合。
对于每一个询问,我们可以枚举找到相应的块,将剩余元素暴力插入,得到 m 个限制条件下分别的满足条件集合,最后和已插入元素求交即可。
$O(q sqrt n m + frac{nmq}{64})$
const int N = 50010,M = 230; struct node { int x[5]; void scan() { FOR(i,0,4) scanf("%d",&x[i]); } }a[N]; bitset<N> blc[5][M],ans[5]; vector<int> pos[5][N]; int n,m,siz,tot,L[M],R[M]; int main() { int T; cin >> T; while(T--) { cin >> n >> m; FOR(i,0,4) FOR(j,1,m) pos[i][j].clear(); FOR(i,1,n) { a[i].scan(); FOR(j,0,4) pos[j][a[i].x[j]].pb(i); } siz = sqrt(m); tot = m/siz+1; FOR(i,0,4) ans[i].reset(); FOR(i,1,tot) { L[i] = max((i-1)*siz,1); R[i] = min(i*siz-1, m); FOR(j,L[i],R[i]) FOR(k,0,4) for(auto x:pos[k][j]) ans[k].set(x); FOR(k,0,4) blc[k][i] = ans[k]; } int q,lastans=0;; node tmp; cin >> q; while(q--) { tmp.scan(); FOR(i,0,4) tmp.x[i]^=lastans; FOR(t,0,4) { ans[t].reset(); int tp; FOR(i,1,tot) if(R[i]>=tmp.x[t]) { tp=i; ans[t]=blc[t][i-1]; break; } FOR(i,L[tp],tmp.x[t]) for(auto x:pos[t][i]) ans[t].set(x); } FOR(i,1,4) ans[0]&=ans[i]; printf("%d ",lastans = ans[0].count()); } } return 0; }
View Code