题目链接:http://hihocoder.com/problemset/problem/1236?sid=873407
求五维偏序,强制在线
b[i][j]表示第i维前j块的状态
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#include<cmath>
#define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
typedef pair<int,int> abcd;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=50005;
bitset<N> b[7][250],ans[7];
int n,B,m;
int cnt,pos[N],l[250],r[250];
abcd a[7][N];
void P(bitset<N> &b){
for (int i=1;i<=n;i++)
dprintf("%d",b.test(i));
dprintf("\n");
}
int main(){
int T,Q,tem,iter,lastans;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(T);
while (T--){
read(n); read(m);
for (int i=1;i<=n;i++)
for (int j=1;j<=5;j++){
read(tem);
a[j][i].first=tem;
a[j][i].second=i;
}
for (int j=1;j<=5;j++) sort(a[j]+1,a[j]+n+1);
int B=sqrt(n);
for (int i=1;i<=n;i++)
pos[i]=(i-1)/B+1;
cnt=pos[n];
for (int i=1;i<=cnt;i++)
l[i]=(i-1)*B+1,r[i]=i*B;
r[cnt]=n;
for (int j=1;j<=5;j++)
for (int i=1;i<=cnt;i++){
b[j][i]=b[j][i-1];
for (int k=l[i];k<=r[i];k++)
b[j][i][a[j][k].second]=1;
}
read(Q);
lastans=0;
while (Q--){
for (int j=1;j<=5;j++){
read(tem); tem^=lastans;
iter=upper_bound(a[j]+1,a[j]+n+1,abcd(tem,1<<30))-a[j]-1;
ans[j]=b[j][pos[iter]-1];
for (int i=l[pos[iter]];i<=iter;i++)
ans[j][a[j][i].second]=1;
}
printf("%d\n",lastans=(ans[1]&ans[2]&ans[3]&ans[4]&ans[5]).count());
}
}
return 0;
}