[hihoCoder1236 Scores 2015BeijingOnline]简单粗暴的分块+简单粗暴的bitset

题意:50000个5维向量,50000次询问每一维都不大于某一向量的向量个数,强制在线。

思路:做完这题才知道bitset效率这么高,自己本地测试了下1s可以操作1010个bit,orz简单粗暴

  • 令S(i)表示第i维比当前向量的i维小的向量集,则答案为count(∩S(i)),0≤i‹5
  • 每个向量都可以和一个id绑定(取下标就行了),绑定后就可以考虑bitset了。分别按每一维排序,每隔√N个位置预处理下当前位置之前的id的bitset
  • 查询时,对每一维二分得到最大位置,然后用1个预处理的结果+最多√N次暴力单bit插入就能得到S(i)。然后就是and和count了。
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
    #include "local.h"
#endif
#define X first
#define Y second
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define mset(a, x) memset(a, x, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
typedef long long ll;
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}

int k;
struct Node {
    int a[5];
    int id;
    void read() {
        for (int i = 0; i < 5; i ++) {
            scanf("%d", a + i);
        }
    }
    bool operator < (const Node &that) const {
        return a[k] < that.a[k];
    }
};
Node stu[1 << 16];
int r[5][1 << 16], id[5][1 << 16];
bitset<1 << 16> bs[5][1 << 8];

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int T, n, q, m;
    cin >> T;
    while (T --) {
        cin >> n >> m;
        for (int i = 0; i < n; i ++) {
            stu[i].read();
            stu[i].id = i;
        }
        int L = sqrt(n + 0.5);
        for (int i = 0; i < 5; i ++) {
            k = i;
            sort(stu, stu + n);
            bitset<1 << 16> bbs;
            for (int j = 0; j < n; j ++) {
                r[i][j] = stu[j].a[i];
                id[i][j] = stu[j].id;
                bbs[stu[j].id] = 1;
                if (j % L == L - 1 || j == n - 1)  {
                    bs[i][j / L] = bbs;
                }
            }
        }
        int lastans = 0;
        cin >> q;
        while (q --) {
            Node qry;
            qry.read();
            bitset<1 << 16> ans;
            for (int i = 0; i < 5; i ++) {
                qry.a[i] ^= lastans;
                bitset<1 << 16> buf;
                int pos = upper_bound(r[i], r[i] + n, qry.a[i]) - r[i];
                if (pos / L) buf = bs[i][pos / L - 1];
                while (pos % L) buf[id[i][-- pos]] = 1;
                if (i) ans &= buf;
                else ans = buf;
            }
            printf("%d
", lastans = ans.count());
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/jklongint/p/4831283.html