题意:

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