POJ 2761 Feed the dogs [离线+treap]

来源:互联网 发布:优化驱动器一共几遍 编辑:程序博客网 时间:2024/05/22 16:48

题意:给出N个数,M个询问,每次询问给出区间(L,R)以及K,问这个区间内第K大的数是多少,同时保证 区间不互相包含。

范围:N<=10W , M<=5W

解法:题意提示离线:即区间不互相包含也就是L,R递增,用treap右加左减维护即可,复杂度O(N*LOG N)

代码:

#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<iostream>#include<stdlib.h>#include<set>#include<map>#include<queue>#include<vector>#include<bitset>#pragma comment(linker, "/STACK:1024000000,1024000000")template <class T>bool scanff(T &ret){ //Faster Input    char c; int sgn; T bit=0.1;    if(c=getchar(),c==EOF) return 0;    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();    sgn=(c=='-')?-1:1;    ret=(c=='-')?0:(c-'0');    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');    if(c==' '||c=='\n'){ ret*=sgn; return 1; }    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;    ret*=sgn;    return 1;}#define inf 1073741823#define llinf 4611686018427387903LL#define PI acos(-1.0)#define lth (th<<1)#define rth (th<<1|1)#define rep(i,a,b) for(ll i=a;i<=b;i++)#define drep(i,a,b) for(ll i=a;i>=b;i--)#define gson(i,root) for(ll i=ptx[root];~i;i=ed[i].next)#define mem(x,val) memset(x,val,sizeof(x))#define mkp(a,b) make_pair(a,b)#define findx(x) lower_bound(b+1,b+1+bn,x)-b#define pb(x) push_back(x)using namespace std;typedef long long ll;int n,m;int a[100100],ans[100100];struct query{    int l,r,k,idx;    bool operator <(const query x)const{        if(l==x.l)return r<x.r;        return l<x.l;    }}q[100100];//treapint tot,root;struct node{    int size,val,rnd,l,r;}t[100100];void maintain(int x){    if(x<=0)return;    t[x].size=t[t[x].l].size+t[t[x].r].size+1;}void lturn(int &x){    int tmp=t[x].r;    t[x].r=t[tmp].l;    t[tmp].l=x;    maintain(x);    x=tmp;}void rturn(int &x){    int tmp=t[x].l;    t[x].l=t[tmp].r;    t[tmp].r=x;    maintain(x);    x=tmp;}void insert(int &x,int val){    if(x==0){        x=++tot;        t[x].val=val;        t[x].size=1;        t[x].rnd=rand();        t[x].l=t[x].r=0;        return;    }    else if(val<t[x].val){        insert(t[x].l,val);        if(t[t[x].l].rnd<t[x].rnd)rturn(x);    }    else{        insert(t[x].r,val);        if(t[t[x].r].rnd<t[x].rnd)lturn(x);    }    maintain(x);}void dele(int &x,int val){    if(val>t[x].val)dele(t[x].r,val);    else if(val<t[x].val)dele(t[x].l,val);    else{        if(t[x].l==0)x=t[x].r;        else if(t[x].r==0)x=t[x].l;        else{            if(t[t[x].l].rnd<t[t[x].r].rnd){                rturn(x);                dele(t[x].r,val);            }            else{                lturn(x);                dele(t[x].l,val);            }        }    }    maintain(x);}int findk(int x,int k){    int lsz=t[t[x].l].size;    int rsz=t[t[x].r].size;    if(k==lsz+1)return t[x].val;    if(k<=lsz)return findk(t[x].l,k);    return findk(t[x].r,k-lsz-1);}int exist(int x,int val){    while(x){        if(t[x].val==val)return 1;        else if(val>t[x].val)x=t[x].r;        else x=t[x].l;    }    return 0;}void init(){    tot=root=0;    rep(i,1,n)scanff(a[i]);    rep(i,1,m)scanff(q[i].l),scanff(q[i].r),scanff(q[i].k),q[i].idx=i;    sort(q+1,q+1+m);}void solve(){    int l=1,r=0;    rep(i,1,m){        for(;r<q[i].r;r++)insert(root,a[r+1]);        for(;l<q[i].l;l++)dele(root,a[l]);        ans[q[i].idx]=findk(root,q[i].k);    }    rep(i,1,m)        printf("%d\n",ans[i]);}main(){    while(scanf("%d%d",&n,&m)!=EOF){        init();        solve();    }}


0 0
原创粉丝点击