5296. 【清华集训2017模拟】Sequence 树套树
2017-08-20 16:01
381 查看
题意:给你一些二元组如(ai,bi),每次询问l,r,x,y,k.
先把元素按照第一关键字排序,取出其中排名为x,y的,按照第二关键字排序后取出排名为k的元素。
树套树很明显了其实。。
对于第一个操作,我们对于a维护一颗主席树,取出第x,y的端点,然后在外层主席树中把第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 ; struct node { int x,y; }a ,b ; 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,& 4000 amp;x,&y,&k); printf("%d\n",solve(l,r,x,y,k)); } return 0; }
相关文章推荐
- 【JZOJ 5296】【清华集训2017模拟】Sequence
- 【JZOJ5296】【清华集训2017模拟】Sequence
- 5483. 【清华集训2017模拟11.26】简单路径
- JZOJ 5496. 【清华集训2017模拟12.09】Tree
- [JZOJ5495]【清华集训2017模拟12.09】MiniumCut
- 【JZOJ 5295】【清华集训2017模拟】Create
- jzoj5317 【清华集训2017模拟8.19】func (寻找性质)
- [JZOJ5485]【清华集训2017模拟11.26】字符串
- [jzoj]5484. 【清华集训2017模拟11.26】快乐树(树形DP)
- [JZOJ5500]【清华集训2017模拟12.10】营养餐
- 【清华集训2017模拟】ces
- JZOJ5489. 【清华集训2017模拟11.28】海明距离
- jzoj5498 【清华集训2017模拟12.10】大佬的难题 巧妙容斥
- JZOJ 5485. 【清华集训2017模拟11.26】字符串
- 【JZOJ5295】【清华集训2017模拟】Create
- 【JZOJ5296】【清华集训模拟】Sequence(整体二分)
- JZOJ 5500. 【清华集训2017模拟12.10】营养餐
- 【清华集训2017模拟11.29】K小数查询
- 【清华集训2017模拟12.10】回文串
- 【清华集训2017模拟】Sequence