Disjoint Sparse Table(不相交散列表)模板

来源:互联网 发布:水晶古筝知乎 编辑:程序博客网 时间:2024/06/07 00:58

今天看到一道题,有1e6个数,2e7个询问,每个询问给出区间[l,r],对每个询问输出区间内的数的乘积mod p,由于时间限制很紧,每个询问基本要O(1)回答,然后我了解到这个数据结构可以解决这类问题,下面是求和的模板。0 indexed

# include <bits/stdc++.h>using namespace std;const int N = 1058576, LOGN = 22;long long v[N][LOGN];long long a[N], n, q;void build(int i, int s, int e){if(s == e) return;int m = (s + e)/2;v[m][i] = a[m];for(int j = m-1; j >= s; j--){v[j][i] = v[j+1][i]+a[j];//改成乘号就是区间乘积}if(m + 1 <= e){v[m+1][i] = a[m+1];for(int j = m+2; j <= e; j++){v[j][i] = v[j-1][i]+a[j];//改成乘号就是区间乘积}}build(i+1, s, m);build(i+1, m+1, e);}int main(){    scanf("%d%d",&n,&q);//n个数,q个询问    int LEV = __builtin_clz(n);    int size = 1<<(31-LEV);    if(n != size)LEV--, size *= 2;    for(int i=0; i<n; ++i) scanf("%d",&a[i]);    build(0,0,size-1);    int q;    while(q--)    {        int l, r;        scanf("%d%d",&l,&r);        --l;--r;        if(l==r)        {            printf("%d\n",a[l]);            continue;        }        unsigned int temp = __builtin_clz(l^r);        unsigned int lev = temp-LEV-1;        int ans = v[r][lev]+v[l][lev];        printf("%d\n",ans);    }    return 0;}


原创粉丝点击