玲珑杯Round20PE

来源:互联网 发布:广州移动宽带 知乎 编辑:程序博客网 时间:2024/05/19 12:14
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>#include <cmath>#define maxn 400100using namespace std;struct Data{    int val,id;};struct Tree{    int l,r,sum;};Data a[maxn];Tree t[maxn*100];int Rank[maxn],Root[maxn],cntt;bool cmp(Data a,Data b){    return a.val<b.val;}void init(){    cntt=1;    Root[0]=0;    t[0].l=t[0].r=t[0].sum=0;    return;}void update(int val,int&root,int l,int r){    t[cntt]=t[root];    t[cntt].sum++;    root=cntt;    cntt++;    if (l==r) return;    int mid=(l+r)/2;    if (val<=mid) update(val,t[root].l,l,mid);    else update(val,t[root].r,mid+1,r);    return;}int query(int rl,int rr,int k,int l,int r){    if (l==r) return l;    int sum=t[t[rr].l].sum-t[t[rl].l].sum;    int mid=(l+r)/2;    if (k<=sum) return query(t[rl].l,t[rr].l,k,l,mid);    else return query(t[rl].r,t[rr].r,k-sum,mid+1,r);}int findx(int rl,int rr,int x,int l,int r){    if (l==r) return t[rr].sum-t[rl].sum;    int sum=t[t[rr].l].sum-t[t[rl].l].sum;    int mid=(l+r)/2;    if (x<=mid) return findx(t[rl].l,t[rr].l,x,l,mid);    else return sum+findx(t[rl].r,t[rr].r,x,mid+1,r);}int trans(int x,int n){    a[n+1].val=0x3f3f3f3f;    int l=1,r=n+1;    while(l<r)    {        int mid=(l+r)/2;        if (a[mid].val<=x) l=mid+1;        else r=mid;    }    return l-1;}int main(){    int n,m;    while(~scanf("%d %d",&n,&m))    {        for (int k=1;k<=n;k++)            {scanf("%d",&a[k].val);a[k].id=k;}        sort(a+1,a+n+1,cmp);        for (int k=1;k<=n;k++)            Rank[a[k].id]=k;        init();        for (int k=1;k<=n;k++)        {            Root[k]=Root[k-1];            update(Rank[k],Root[k],1,n);        }        for (int k=1;k<=m;k++)        {            int l,r,x,k1,k2,kx,tranx;            int ans1,ans2;            scanf("%d %d %d %d %d",&l,&r,&x,&k1,&k2);            int st,en;            st=query(Root[l-1],Root[r],1,1,n);            en=query(Root[l-1],Root[r],r-l+1,1,n);            st=a[st].val;en=a[en].val;            if (x<st)            {                ans1=-1;                if (k2<=r-l+1) ans2=a[query(Root[l-1],Root[r],k2,1,n)].val;                else ans2=-1;            }            else if (x>en)            {                ans2=-1;                if (k1<=r-l+1) ans1=a[query(Root[l-1],Root[r],k1,1,n)].val;                else ans1=-1;            }            else            {                tranx=trans(x,n);                kx=findx(Root[l-1],Root[r],tranx,1,n);                if (k1<=kx) ans1=a[query(Root[l-1],Root[r],k1,1,n)].val;                else ans1=-1;                if (k2+kx<=r-l+1) ans2=a[query(Root[l-1],Root[r],k2+kx,1,n)].val;                else ans2=-1;            }            printf("%d %d\n",ans1,ans2);        }    }    return 0;}



这题目的关键就是如果知道x在l,r中,我们要求<=x是第几个

这里加了两个函数,第一个transx是找第一个>=x的值离散化的值-1

findx就是找x(离散化过的)的位置

原创粉丝点击