【SPOJ KQUERY】【HDU 4417】靜態區間rank查詢

來源:互聯網
上載者:User

SPOJ KQUERY:給一個數列,查詢x在區間l,r上有多少數字>x

HDU4417:給一個數列,查詢x在區間l,r上有多少數字<=x

離線樹狀數組,線上主席樹,都可以做到logn複雜度的查詢,不過主席樹的常數超級大,SPOJ那題打死都是TLE,不能直視~

樹狀數組做法是先對所有詢問按x從小到大排序,然後把原數列裡<=x的數按下標加入樹狀數組,每次查詢區間lr的區間和。

代碼如下:

SPOJ KQUERY

int z[NN],a[NN],b[NN],lb;int u[MM],v[MM],w[MM],id[MM],ans[MM];int n,m;void update(int x){while (x<=n){z[x]++;x+=lowbit(x);}}int sum(int x){int ans=0;while (x>0){ans+=z[x];x-=lowbit(x);}return ans;}int cmp(int i,int j){return w[i]<w[j];}int cmp2(int i,int j){return a[i]<a[j];}int main(){n=fastget();for(int i=1;i<=n;i++)a[b[i]=i]=fastget();m=fastget();for(int i=1;i<=m;i++){u[i]=fastget();v[i]=fastget();w[i]=fastget();id[i]=i;}sort(id+1,id+1+m,cmp);sort(b+1,b+1+n,cmp2);int j=1;for(int i=1;i<=m;i++){for(;j<=n;j++)if(a[b[j]]<=w[id[i]]) update(b[j]);else break;ans[id[i]]=v[id[i]]-u[id[i]]+1-(sum(v[id[i]])-sum(u[id[i]]-1));}for(int i=1;i<=m;i++)fastput(ans[i]);return 0;}

主席樹做法:

數列離散化,按權值建線段樹,建樹方式和POJ2104一樣,查詢的時候如果區間的mid>=x就查詢左子樹,否則左子樹和加上右子樹的查詢結果。

int a[NN],b[NN],lb,n,m;struct segmenttree{    int l,r,s;}tree[NN*25];int node;int root[NN];int search(int x){    int l=0,r=lb,mid;    while (l<r)    {        mid=l+r+1>>1;        if(b[mid]<=x) l=mid;        else r=mid-1;    }    return l;}int build(int l,int r){    int k=++node;    tree[k].s=0;    if(l==r) return k;    int m=l+r>>1;    if(l<=m) tree[k].l=build(l,m);    if(r>m) tree[k].r=build(m+1,r);    return k;}int change(int rt,int l,int r,int x){    int k=++node,root=k,mid;    tree[k]=tree[rt];    tree[k].s++;    while (l<r)    {        mid=l+r>>1;        if(x<=mid)        {            rt=tree[rt].l;            tree[k].l=++node;            k=node;            tree[k]=tree[rt];            tree[k].s++;            r=mid;        }        else        {            rt=tree[rt].r;            tree[k].r=++node;            k=node;            tree[k]=tree[rt];            tree[k].s++;            l=mid+1;        }    }    return root;}int query(int L,int R,int l,int r,int x){    int mid,ans=0;    while (l<r)    {        mid=l+r>>1;        if(mid>=x)        {            r=mid;            L=tree[L].l;            R=tree[R].l;        }        else        {            l=mid+1;            ans+=tree[tree[R].l].s-tree[tree[L].l].s;            L=tree[L].r;            R=tree[R].r;        }    }    if(l==r)    {        if(x<l) return 0;        else return ans+tree[R].s-tree[L].s;    }}int u,v,w,i;int main(){    int tt=fastget();    for(int cs=1;cs<=tt;cs++)    {        n=fastget();        m=fastget();        for(i=1;i<=n;i++)            b[i]=a[i]=fastget();        lb=1;        sort(b+1,b+1+n);        for(i=2;i<=n;i++)            if(b[i]!=b[lb]) b[++lb]=b[i];        node=0;        root[0]=build(1,lb);        for(i=1;i<=n;i++)            root[i]=change(root[i-1],1,lb,search(a[i]));        printf("Case %d:\n",cs);        while (m--)        {            u=fastget(),v=fastget(),w=fastget();            u++; v++;            w=search(w);            if(w==0) fastput(0);            else fastput(query(root[u-1],root[v],1,lb,w));        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.