分块+二分维护,求区间内数字出现的次数

来源:互联网 发布:java游戏服务器架构 编辑:程序博客网 时间:2024/05/16 04:23

如题,把区间分块,对每个块里的数字排序,然后在块里二分查找,复杂度理论是O(n^1.5*logn)

csy菊苣说把块的大小调整为n*log2(n),复杂度可以降到O(n*sqrt(n*logn))

然后我写了组大随机数据测试了一下,如果分块大小是sqrt(n)用了7.6s,分块大小是n*log2(n)时只用了3.6s!!

效率提升了非常多倍,感觉又是黑科技的节奏,收藏了

const int MX = 1e5 + 5;struct Data {    int x, id;    bool operator<(const Data &P) const {        return x < P.x;    }};Data A[MX];int W, n;void init() {    W = sqrt(n * log2(n));    int e = (n - 1) / W + 1;    for(int i = 1; i <= e; i++) {        sort(A + (i - 1)*W + 1, A + min(i * W, n) + 1);    }}int solve(int L, int R, int x) {    int ret = 0, l = (L - 1) / W + 1, r = (R - 1) / W + 1;    for(int i = (l - 1) * W + 1; i <= min(l * W, n); i++) {        if(A[i].x == x && A[i].id >= L) ret++;    }    if(l == r) return ret;    for(int i = (r - 1) * W + 1; i <= min(r * W, n); i++) {        if(A[i].x == x && A[i].id <= R) ret++;    }    Data p; p.x = x;    for(int i = l + 1; i <= r - 1; i++) {        ret += upper_bound(A + (i - 1) * W + 1, A + i * W + 1, p) - lower_bound(A + (i - 1) * W + 1, A + i * W + 1, p);    }    return ret;}


0 0
原创粉丝点击