五维偏序模板(bitset+分块)

很简单的维护一下分块就可以了

似乎也不需要多讲什么

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    char ch=getchar();
    int res=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    return res*f;
}
const int N=1e5;
struct node{
	int val,id;
	node(){}
	node(int _v,int _i):val(_v),id(_i){}
	bool operator <(const node &a)const{
		return val==a.val?id<a.id:val<a.val;
	}
}a[6][N];
bitset<N>bit[6][300];
bitset<N>ans,tmp;
int n,m,q,blo,num;
int main(){
	int T=read();
	while(T--){
		n=read(),m=read();
		for(int i=1;i<=n;i++){
			for(int j=1;j<=5;j++){
				a[j][i].val=read(),a[j][i].id=i;
			}
		}
		for(int i=1;i<=5;i++)sort(a[i]+1,a[i]+n+1);
		blo=sqrt(n);
		for(int i=1;i<=5;i++){
			for(int j=1;(j-1)*blo<n;j++){
				bit[i][j].reset();
				bit[i][j]=bit[i][j-1];
				int now=(j-1)*blo;
				for(int k=1;k<=blo&&now+k<=n;k++){
					bit[i][j].set(a[i][now+k].id);
				}
			}
		}
		q=read();
		int now[6],pre=0;
		while(q--){
			for(int i=1;i<=5;i++)now[i]=read(),now[i]^=pre;
			ans.reset();
			for(int i=1;i<=5;i++){
				int pos=lower_bound(a[i]+1,a[i]+n+1,node(now[i],n+1))-a[i]-1;
				pos/=blo;
				tmp=bit[i][pos];
				for(int j=pos*blo+1;a[i][j].val<=now[i]&&j<=n;j++){
					tmp.set(a[i][j].id);
				}
				if(i==1)ans=tmp;
				else ans&=tmp;
			}
			cout<<(pre=ans.count())<<'\n';
		}
	}
}
posted @ 2019-03-08 07:47  Stargazer_cykoi  阅读(227)  评论(0编辑  收藏  举报