5296. 【清华集训2017模拟】Sequence 树套树

来源:互联网 发布:经典数据新闻案例分析 编辑:程序博客网 时间:2024/05/19 18:16

题意:给你一些二元组如(ai,bi),每次询问l,r,x,y,k.
先把元素按照第一关键字排序,取出其中排名为x,y的,按照第二关键字排序后取出排名为k的元素。

树套树很明显了其实。。
对于第一个操作,我们对于a维护一颗主席树,取出第x,y的端点,然后在外层主席树中把第x到y中的节点信息取出来然后做个线段树区间k大就好了。。

#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=3e5+5;int n,m,sz,tot,root[N];struct node{    int x,y;}a[N],b[N];struct tree{    int l,r,s,root;}t[N*30];inline void ins(int &x,int y,int l,int r,int v){    x=++sz;    t[x]=t[y];    t[x].s++;    if (l==r)return;    int mid=(l+r)/2;    if (v<=mid)ins(t[x].l,t[y].l,l,mid,v);    else ins(t[x].r,t[y].r,mid+1,r,v);}inline void ins(int &x,int y,int l,int r,int v1,int v2){    x=++sz;    t[x]=t[y];    t[x].s++;    ins(t[x].root,t[y].root,1,n,v2);    if (l==r)return;    int mid=(l+r)>>1;    if (v1<=mid)ins(t[x].l,t[y].l,l,mid,v1,v2);    else ins(t[x].r,t[y].r,mid+1,r,v1,v2);}inline int kth(int x,int y,int l,int r,int k){    if (l==r)return l;    int mid=(l+r)>>1;    if (t[t[x].l].s-t[t[y].l].s>=k)return kth(t[x].l,t[y].l,l,mid,k);    else return kth(t[x].r,t[y].r,mid+1,r,k-t[t[x].l].s+t[t[y].l].s);}inline void get(int x,int y,int l,int r,int l1,int r1){    if (l1>r1)return;    if (l==l1&&r==r1)    {        tot++;        b[tot].x=t[x].root;        b[tot].y=t[y].root;        return;    }    int mid=(l+r)/2;    get(t[x].l,t[y].l,l,mid,l1,min(r1,mid));    get(t[x].r,t[y].r,mid+1,r,max(l1,mid+1),r1);}inline int solve(int l,int r,int x,int y,int k){    x=kth(root[r],root[l-1],1,n,x);    y=kth(root[r],root[l-1],1,n,y);    tot=0;    get(root[r],root[l-1],1,n,x,y);    l=1,r=n;    while (l<r)    {        int mid=(l+r)>>1,s=0;        fo(i,1,tot)s+=t[t[b[i].x].l].s-t[t[b[i].y].l].s;        if (s>=k)        {            fo(i,1,tot)b[i].x=t[b[i].x].l,b[i].y=t[b[i].y].l;            r=mid;        }        else        {            fo(i,1,tot)            {                k-=t[t[b[i].x].l].s-t[t[b[i].y].l].s;                b[i].x=t[b[i].x].r;                b[i].y=t[b[i].y].r;            }            l=mid+1;        }    }    return l;}int main(){    freopen("sequence.in","r",stdin);    freopen("sequence.out","w",stdout);    scanf("%d",&n);    fo(i,1,n)scanf("%d",&a[i].x);    fo(i,1,n)scanf("%d",&a[i].y);    fo(i,1,n)ins(root[i],root[i-1],1,n,a[i].x,a[i].y);    scanf("%d",&m);    while (m--)    {        int l,r,x,y,k;        scanf("%d%d%d%d%d",&l,&r,&x,&y,&k);        printf("%d\n",solve(l,r,x,y,k));    }    return 0;}