hihoCoder 1236 Scores(2015 北京网赛 J)

Scores

        有n个五维的向量,给q个询问,每个询问是一个五维向量,回答有多少个向量没有一维大于它。对每一维分别排序,然后以若干个[比如sqrt(n)]为一段,压到一个bitset去,对每个询问求每维结果,与运算后count1的个数。

        注意这题有个坑人的条件,就是除第一个询问外,之后每个询问都要和前一个结果异或一下。。我没看到跪了无数发。

#include <bits/stdc++.h>    
using namespace std; 

#define ll long long

const int maxn = 50010;

struct node{
	int id;
	int score;
	bool operator<(const node& other)const{
		if(score!=other.score)return score<other.score;
		return id<other.id;
	}
	node(int id,int score):id(id),score(score){
	}
	node(){
	}
};

bitset<maxn> bs[6][250];
node a[6][maxn];
bitset<maxn> ans;

int main(){
	int t;
	cin>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		
		for(int j=1;j<=n;j++){
			for(int i=1;i<=5;i++){
				scanf("%d",&a[i][j].score);
				a[i][j].id=j;
			}
		}
		for(int i=1;i<=5;i++)sort(a[i]+1,a[i]+n+1);
		
		int SQRT = sqrt(n);
		for(int i=1;i<=5;i++){
			for(int div=1;(div-1)*SQRT<n;div++){
				bs[i][div].reset();
				bs[i][div]=bs[i][div-1];
				int start=(div-1)*SQRT;
				for(int j=1;j<=SQRT;j++){
					if(start+j>n)break;
					bs[i][div].set(a[i][start+j].id);
				}
			}
		}
		int q;
		cin>>q;
		int Last=0;
		while(q--){
			int b[6];
			for(int i=1;i<=5;i++){
				scanf("%d",&b[i]);
				b[i]^=Last;
			}
			
			ans.reset();
			int tmp = lower_bound(a[1]+1,a[1]+n+1, node(n+1,b[1]) )-(a[1]+1);
			tmp=tmp/SQRT;			
			ans = bs[1][tmp];
			for(int j=tmp*SQRT+1;a[1][j].score<=b[1]&&j<=n;j++){
				ans.set(a[1][j].id);
			}
			for(int i=2;i<=5;i++){
				tmp = lower_bound(a[i]+1,a[i]+n+1, node(n+1,b[i]) )-(a[i]+1);
				tmp=tmp/SQRT;
				bitset<maxn> tbs = bs[i][tmp];
				for(int j=tmp*SQRT+1;a[i][j].score<=b[i]&&j<=n;j++){
					tbs.set(a[i][j].id);
				}
				ans &= tbs;
			}
			int re=ans.count();
			Last=re;
			printf("%d\n",re);
		}
	}
	return 0;
}



你可能感兴趣的:(bitset,分块,2015ICPC,北京网赛)