hihoCoder 1236 bitset + 分块

来源:互联网 发布:剑网三纣炀的捏脸数据 编辑:程序博客网 时间:2024/06/05 00:50

hihoCoder 1236
题意:给一份成绩单,成绩单上有5门成绩,成绩范围在1~m,然后询问q次,每次给一个人的成绩问每科成绩的分数都低于他的人有多少。
思路:bitset里标记一下成绩在某个数值以下有哪些人,最后5个bitset的交集就是答案。
但是空间需要Onm并不够用,所以要对人数进行排序分块。
另外这个题强制在线,每次询问的成绩需要和上次询问的答案做异或。

#include <bits/stdc++.h>using namespace std;const int M = 5e4 + 10;struct Node{    int v, pos;    Node(){}    Node(int a, int b):v(a), pos(b){}    bool operator <(const Node &i) const {        return v == i.v ? pos < i.pos : v < i.v;    }}node[6][M];bitset<M>bt[6][300], ans, tmp;main(){ //   freopen("in.in", "r", stdin);    int t;    scanf("%d", &t);    while(t--){        int n, m;        memset(node, 0, sizeof node);        for(int i = 0; i < 6; i++)            for(int j = 0; j < 300; j++)                bt[i][j].reset();        scanf("%d %d", &n, &m);        for(int i = 0; i < n; i++){            for(int j = 0; j < 5; j++){                scanf("%d", &node[j][i].v);                node[j][i].pos = i;            }        }        int sqr = sqrt(n);        for(int i = 0; i < 5; i++) sort(node[i], node[i] + n);        int pb = 0;        for(int i = 0; i < 5; i++){            for(int j = 0; j < n; j++){                if(j / sqr != pb) bt[i][pb + 1] = bt[i][pb];                bt[i][j / sqr].set(node[i][j].pos);                pb = j / sqr;            }        }        int q;        scanf("%d", &q);        int pre = 0, query[6];        while(q--){            ans.reset(), ans.flip();            for(int i = 0; i < 5; i++){                scanf("%d", &query[i]);                query[i] ^= pre;            }            for(int i = 0; i < 5; i++){                tmp.reset();                int p = lower_bound(node[i], node[i] + n, Node(query[i], n)) - node[i] - 1;                int pp = p / sqr;                if(pp != 0) tmp = bt[i][pp - 1];                for(int j = pp * sqr; j < n; j++){                    if(node[i][j].v > query[i]) break;                    tmp.set(node[i][j].pos);                }                ans &= tmp;            }            pre = ans.count();            printf("%d\n", pre);        }    }}
0 0