HDU 4417-树状数组求区间rank查询/主席树区间rank查询

来源:互联网 发布:c语言智能五子棋游戏 编辑:程序博客网 时间:2024/06/04 19:23

主席树做法:

离散化下标,直接求累计区间里小于等于query_k的个数  ,这题似乎跑得时间都差不多。

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;const int MAXNN=100005;#define w(i) T[(i)].w#define ls(i) T[(i)].ls#define rs(i) T[(i)].rsint n;struct node{    int ls,rs,w;    node()    {        ls=rs=w=0;    }} T[MAXNN*25];int a[MAXNN],b[MAXNN],root[MAXNN],sz,m;void insert(int &i,int l,int r,int x){    T[++sz]=T[i];    i=sz;    w(i)++;    if (l==r) return;    int m=(l+r)>>1;    if (x<=m) insert(ls(i),l,m,x);    else insert(rs(i),m+1,r,x);}int query(int i,int j,int l,int r,int k){    if (l==r) return r<=k?(w(j)-w(i)):0;    int t=w(ls(j))-w(ls(i));    int m=(l+r)>>1;    if (k>=m) return t+query(rs(i),rs(j),m+1,r,k);    else  return query(ls(i),ls(j),l,m,k);}int main(){    //DO YOLO  //  freopen("in.txt","r",stdin);    int m;    int t;    int cnt=1;    cin>>t;    while(t--)    {        root[0]=0;        sz=0;        cin>>n>>m;        int i;        int nn=n;        for (i=1; i<=n; i++) scanf("%d",& a[i]),b[i]=a[i];        sort(b+1,b+1+n);        int size =unique(b+1,b+1+n)-b-1;        b[size+1]=2000000000;        for (  i=1; i<=n; i++)        {            root[i]=root[i-1];            a[i]=lower_bound(b+1,b+1+size,a[i])-b;            insert(root[i],1,size,a[i]);        }        printf("Case %d:\n",cnt++);        //支持操作:        //QUERY(s,t,k):query(root[s-1],root[T],1,n,k);        int x,y,k;        for (i=1; i<=m; i++)        {            scanf("%d%d%d",&x,&y,&k);            x++,y++;            k=upper_bound(b+1,b+1+size+1,k)-b;             int ret=query(root[x-1],root[y],1,size,k-1);            printf("%d\n",ret);        }    }    return 0;}



树状数组:

把询问和元数组都排序,离线处理

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;const int maxn=100010;const double pi=acos(-1.0);double eps=0.000001;struct A{    int key,id;}a[maxn];struct B{    int l,r,key,id,ans;}b[maxn];int n,m;int tree[maxn];   int lowbit(int x){return x&-x;}void add(int x,int value){for (int i=x;i<=n;i=i+lowbit(i)){tree[i]+=value;}}int get(int x){int sum=0;for (int i=x;i;i-=lowbit(i)){sum+=tree[i];}return sum;}bool cmp1(A x,A y){    return x.key<y.key;}bool cmp2(B x,B y){    return x.key<y.key;}bool cmp3(B x,B y){    return x.id<y.id;}int main(){    int tt,cas=0;   scanf("%d",&tt);   while (tt--)   {       scanf("%d%d",&n,&m);       memset(tree,0,sizeof(tree));       for (int i=1; i<=n; i++)       {           int x;scanf("%d",&x);           a[i].key=x; a[i].id=i;       }       sort(a+1,a+1+n,cmp1);       for (int i=1; i<=m; i++)       {           scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].key);           b[i].l++; b[i].r++;           b[i].id=i; b[i].ans=0;       }       sort(b+1,b+1+m,cmp2);       int j=1;       for (int i=1; i<=m; i++)       {           while (b[i].key>=a[j].key && j<=n)           {               add(a[j].id,1);               j++;           }           b[i].ans=get(b[i].r)-get(b[i].l-1);       }       sort(b+1,b+1+m,cmp3);       printf("Case %d:\n",++cas);       for (int i=1; i<=m; i++)            printf("%d\n",b[i].ans);   }    return 0;}


0 0
原创粉丝点击