主席树 专题

来源:互联网 发布:windows vista 镜像 编辑:程序博客网 时间:2024/06/08 22:25

poj2104
kO(nlogn),O(nlogn)
kroot[r]root[l1]


模板:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           100010#define   MAXN          500005#define   maxnode       5#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-6;const LL     mod   = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int a[MAX];int b[MAX];struct Node{    int l,r,c;}tr[MAX*20];int root[MAX];int sz;int build(int l,int r){    int k=sz++;    if(l==r){        tr[k].c=0;        return k;    }    int mid=(l+r)/2;    tr[k].l=build(l,mid);    tr[k].r=build(mid+1,r);    return k;}int update(int rt,int l,int r,int pos,int d){    int k=sz++;    tr[k].c=tr[rt].c+1;    if(l==r) return k;    int mid=(l+r)/2;    if(pos<=mid){        tr[k].r=tr[rt].r;        tr[k].l=update(tr[rt].l,l,mid,pos,d);    }    else{        tr[k].l=tr[rt].l;        tr[k].r=update(tr[rt].r,mid+1,r,pos,d);    }    return k;}int query(int lr,int rr,int l,int r,int k){    if(l==r) return l;    int mid=(l+r)/2;    if(tr[tr[rr].l].c-tr[tr[lr].l].c>=k) return query(tr[lr].l,tr[rr].l,l,mid,k);    else return query(tr[lr].r,tr[rr].r,mid+1,r,k-(tr[tr[rr].l].c-tr[tr[lr].l].c));}int main(){    //freopen("in.txt","r",stdin);    int n,m;    cin>>n>>m;    for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];    sort(b+1,b+n+1);    int tot=unique(b+1,b+n+1)-b-1;    sz=0;    root[0]=build(1,tot);    for(int i=1;i<=n;i++){        int pos=lower_bound(b+1,b+tot+1,a[i])-b;        root[i]=update(root[i-1],1,tot,pos,1);    }    while(m--){        int l,r,k;        scanf("%d%d%d",&l,&r,&k);        printf("%d\n",b[query(root[l-1],root[r],1,tot,k)]);    }    return 0;}

HDU4417
h
[1,i]线
root[r]hroot[l1]h


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           100010#define   MAXN          500005#define   maxnode       5#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-6;const LL     mod   = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int a[MAX];int b[MAX];struct Node{    int l,r,c;}tr[MAX*20];int root[MAX];int sz;int build(int l,int r){    int k=sz++;    if(l==r){        tr[k].c=0;        return k;    }    int mid=(l+r)/2;    tr[k].l=build(l,mid);    tr[k].r=build(mid+1,r);    return k;}int update(int rt,int l,int r,int pos,int d){    int k=sz++;    tr[k].c=tr[rt].c+1;    if(l==r) return k;    int mid=(l+r)/2;    if(pos<=mid){        tr[k].r=tr[rt].r;        tr[k].l=update(tr[rt].l,l,mid,pos,d);    }    else{        tr[k].l=tr[rt].l;        tr[k].r=update(tr[rt].r,mid+1,r,pos,d);    }    return k;}int query(int lr,int rr,int l,int r,int L,int R){    if(L<=l&&r<=R) return tr[rr].c-tr[lr].c;    int mid=(l+r)/2;    int ans=0;    if(L<=mid) ans+=query(tr[lr].l,tr[rr].l,l,mid,L,R);    if(R>mid) ans+=query(tr[lr].r,tr[rr].r,mid+1,r,L,R);    return ans;}int main(){    //freopen("in.txt","r",stdin);    int t,kase=0;    cin>>t;    while(t--){        int n,m;        kase++;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];        sort(b+1,b+n+1);        int tot=unique(b+1,b+n+1)-b-1;        root[0]=build(1,tot);        for(int i=1;i<=n;i++){            int pos=lower_bound(b+1,b+tot+1,a[i])-b;            root[i]=update(root[i-1],1,tot,pos,1);        }        printf("Case %d:\n",kase);        while(m--){            int l,r,h;            scanf("%d%d%d",&l,&r,&h);            if(l>r) swap(l,r);            l++;r++;            int pos=upper_bound(b+1,b+tot+1,h)-b-1;            if(pos<1) printf("0\n");            else printf("%d\n",query(root[l-1],root[r],1,tot,1,pos));        }    }    return 0;}

SPOJDQUERY

[1,i]a[i]
pre[a[i]]i++++
[l,r],root[r][l,r]


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           30010#define   MAXN          1000005#define   maxnode       5#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-6;const LL     mod   = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int a[MAX];int b[MAX];struct Node{    int l,r,c;}tr[MAX*20];int root[MAX];int pre[MAX];int sz;int build(int l,int r){    int k=sz++;    if(l==r){        tr[k].c=0;        return k;    }    int mid=(l+r)/2;    tr[k].l=build(l,mid);    tr[k].r=build(mid+1,r);    return k;}int update(int rt,int l,int r,int pos,int d){    int k=sz++;    tr[k].c=tr[rt].c+d;    if(l==r) return k;    int mid=(l+r)/2;    if(pos<=mid){        tr[k].r=tr[rt].r;        tr[k].l=update(tr[rt].l,l,mid,pos,d);    }    else{        tr[k].l=tr[rt].l;        tr[k].r=update(tr[rt].r,mid+1,r,pos,d);    }    return k;}int query(int rt,int l,int r,int L,int R){    if(L<=l&&r<=R) return tr[rt].c;    int mid=(l+r)/2;    int ans=0;    if(L<=mid) ans+=query(tr[rt].l,l,mid,L,R);    if(R>mid) ans+=query(tr[rt].r,mid+1,r,L,R);    return ans;}int main(){    //freopen("in.txt","r",stdin);    int n;    while(cin>>n){        for(int i=1;i<=n;i++) RI(a[i]),b[i]=a[i];        sort(b+1,b+n+1);        mem(pre,-1);        int tot=unique(b+1,b+n+1)-b-1;        sz=0;        root[0]=build(1,n);        for(int i=1;i<=n;i++){            int pos=lower_bound(b+1,b+tot+1,a[i])-b;            if(pre[pos]==-1) root[i]=update(root[i-1],1,n,i,1);            else {                int tmp=update(root[i-1],1,n,pre[pos],-1);                root[i]=update(tmp,1,n,i,1);            }            pre[pos]=i;        }        int m;        cin>>m;        while(m--){            int l,r;            RI(l);RI(r);            printf("%d\n",query(root[r],1,n,l,r));        }    }    return 0;}
0 0