hdu 4417 Super Mario(主席树)

来源:互联网 发布:大数据 精准医疗 案例 编辑:程序博客网 时间:2024/05/30 05:28

题解:http://www.cnblogs.com/JKAI/p/7389132.html
不看题解想不到怎么做,对主席树理解的好差劲。。
思路:首先要离散化,离散化的排序数组是rec,对于每个询问L,R,H,对于H,只要找到rec[upper_bound(H)],则要求的数字肯定是在rec[1]—rec[upper_bound(H)],然后主席树求在(L,R)区间中,在rec[1]—rec[upper_bound(H)]范围内的数字即可。

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5+10;int n,m,cnt,root[MAXN],xx,yy;struct node{    int l,r,sum;}T[MAXN*20];int num[MAXN];vector<int> rec;int getid(int x){    return lower_bound(rec.begin(),rec.end(),x)-rec.begin()+1;}void init(){    memset(T,0,sizeof(T));    memset(root,0,sizeof(root));    rec.clear();    cnt = 0;}void update(int l, int r, int& x, int y, int pos){    T[++cnt] = T[y];    T[cnt].sum++;    x = cnt;    if(l == r) return;    int mid = (l+r) >> 1;    if(pos <= mid) update(l,mid,T[x].l,T[y].l,pos);    else update(mid+1,r,T[x].r,T[y].r,pos);}int query(int l, int r, int x, int y){    if(xx > yy) return 0;    if(l >= xx && r <= yy)        return T[y].sum - T[x].sum;    int mid = (l+r) >> 1;    int ret = 0;    if(xx <= mid) ret += query(l,mid,T[x].l,T[y].l);    if(yy > mid) ret += query(mid+1,r,T[x].r,T[y].r);    return ret;}int main(){    //freopen("res.txt","w",stdout);    int t,k;    scanf("%d",&t);    for(int tt = 1; tt <= t; ++tt)    {        init();        scanf("%d %d",&n,&m);        for(int i = 1; i <= n; ++i)        {            scanf("%d",&num[i]);            rec.push_back(num[i]);        }        sort(rec.begin(),rec.end());        rec.erase(unique(rec.begin(),rec.end()),rec.end());        for(int i = 1; i <= n; ++i)        {            update(1,n,root[i],root[i-1],getid(num[i]));        }        printf("Case %d:\n",tt);        for(int i = 1; i <= m; ++i)        {            int ll,rr,kk;            scanf("%d %d %d",&ll,&rr,&kk);            ++ll;            ++rr;            xx = 1;            yy = upper_bound(rec.begin(),rec.end(),kk) - rec.begin();            printf("%d\n",query(1,n,root[ll-1],root[rr]));        }    }}
原创粉丝点击