题意:第i种生物有k[i]个特征,分数是score[i],现在要参加竞赛,报出一种生物a,和一些特征h[i],参加竞赛的所有生物在这些h[i]上面的特征是一样的,a生物有h[i],则所有竞赛的生物都必须有h[i],a生物没有,竞赛的生物也没有,没有提到的则不用管。问你在竞赛中a的排名
思路:特征最多只有10中,所有可以用二进制的每一位表示特征的状态,并记录下每种状态下的生物的类型。现在给你生物的状态,首先要求出能参加竞赛的生物的种类。当 (i&p == t[a]&p) 时,所有拥有i状态的生物就是可以参加竞赛的。再用二分找到在这些类型中a的位置,加起来便是排名了
1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #include <string> 10 #include <cstring> 11 #include <map> 12 #include <stack> 13 #include <set> 14 #define LL long long 15 #define eps 1e-8 16 #define INF 0x3f3f3f3f 17 #define MAXN 10005 18 using namespace std; 19 int G[1100][MAXN]; 20 int s[MAXN], t[MAXN]; 21 vector<int> f[1100]; 22 int main() 23 { 24 #ifndef ONLINE_JUDGE 25 freopen("in.txt", "r", stdin); 26 //freopen("out.txt", "w", stdout); 27 #endif // OPEN_FILE 28 int n, k, m; 29 scanf("%d%d", &n, &k); 30 int x, y, p; 31 for(int i = 0; i < 1025; i++){ 32 G[i][0] = 0; 33 } 34 for(int i = 1; i <= n; i++){ 35 scanf("%d%d", &s[i], &y); 36 p = 0; 37 for(int j = 1; j <= y; j++){ 38 scanf("%d", &x); 39 p |= 1 << (x - 1); 40 } 41 f[p].push_back(s[i]); 42 t[i] = p; 43 G[p][0]++; 44 G[p][G[p][0]] = s[i]; 45 } 46 for(int i = 0; i <= 1025; i++){ 47 sort(G[p], G[p] + G[p][0]); 48 sort(f[i].begin(), f[i].end()); 49 } 50 scanf("%d", &m); 51 int q; 52 int ans; 53 for(int i = 1; i <= m; i++){ 54 scanf("%d%d", &x, &y); 55 p = 0; 56 for(int j = 1; j <= y; j++){ 57 scanf("%d", &q); 58 p |= 1 << (q - 1); 59 } 60 ans = 1; 61 for(int i = 0; i <= 1025; i++){ 62 if((i & p) != (t[x] & p))continue; 63 ans += f[i].size() - (upper_bound(f[i].begin(), f[i].end(), s[x]) - f[i].begin()); 64 continue; 65 int left = 1, right = G[i][0]; 66 while(left < right){ 67 int mid = (left + right) >> 1; 68 if(G[i][mid] > s[x]){ 69 right = mid; 70 } 71 else{ 72 left = mid + 1; 73 } 74 } 75 if(G[i][left] == s[x]) continue; 76 //ans += left - 1; 77 //continue; 78 if(G[i][left] > s[x]){ 79 ans += left; 80 } 81 else if(G[i][left] < s[x]){ 82 ans += left - 1; 83 } 84 //ans += left; 85 //if(G[i][left] == s[x]) 86 //ans += left -1; 87 } 88 printf("%d ", ans); 89 } 90 }