【JZOJ5296】【清华集训2017模拟】Sequence
来源:互联网 发布:java导出excel表格方法 编辑:程序博客网 时间:2024/06/05 00:08
Description
Data Constraint
Solution
对于S和S’,我们可以用主席树很轻松的求出,但不能求出二关键字的k大。所以我们考虑整体二分。我们可以求出排名在[x,y]内的元素的范围[a,b]。对于一个范围[l,r]设满足排名k在该区间的询问[x,y],我们二分出mid,对于一个询问,若满足区间[l,r]内第一关键字在[a,b]且满足第二关键字小于mid的数量少于k,则答案一定在[l,mid]内。因为满足区间[l,r]内因为第二关键字是排列,我们将第二关键字在[l,mid]内的元素按位置排序,并将询问拆成[1,l-1],[1,r]两个询问,然后维护一个指针时期插入的数的位置小于询问,将第一关键字插入至树状数组查询即可。时间复杂度O(
Code
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int maxn=3e4+5,maxn1=2e5+5;struct code{ int l,r,num;}f[maxn*20];struct code2{ int x,id;}c[maxn]; struct code1{ int l,r,x,y,k,id;}q[maxn1],q1[maxn1];int a[maxn1],b[maxn1],d[maxn1],ans[maxn1],g[maxn1];int n,m,i,t,j,k,l,x,y,z,num;bool cmp(code2 x,code2 y){ return x.x<y.x;}bool cmp1(code2 x,code2 y){ return x.id<y.id;}bool cmp2(code1 x,code1 y){ return x.l<y.l;}void insert(int l,int r,int &v,int x){ int mid=(l+r)/2; f[++num]=f[v];v=num;f[v].num++; if (l==r) return; if (mid>=x) insert(l,mid,f[v].l,x); else insert(mid+1,r,f[v].r,x);}void find(int l,int r,int v,int v1,int x){ int mid=(l+r)/2; if (l==r){ t=l;return; } if (x>f[f[v].l].num-f[f[v1].l].num) find(mid+1,r,f[v].r,f[v1].r,x-(f[f[v].l].num-f[f[v1].l].num)); else find(l,mid,f[v].l,f[v1].l,x);}void insert1(int x,int z){ while (x<=n) g[x]+=z,x+=(x&(-x));}int find1(int x){ int t=0; while (x>0) t+=g[x],x-=(x&(-x)); return t;}void dg(int l,int r,int x,int y){ int mid=(l+r)/2; if (x>y) return; if (l==r){ for (i=x;i<=y;i++) ans[q[i].id]=l; return; } sort(c+l,c+mid+1,cmp1); num=0; for (i=x;i<=y;i++){ q1[++num]=q[i];q1[++num]=q[i];q1[num-1].l--; q1[num].l=q[i].r;q1[num-1].r=-1;q1[num].r=1; } sort(q1+1,q1+num+1,cmp2);j=l; for (i=1;i<=num;i++){ while (c[j].id<=q1[i].l && j<=mid) insert1(a[c[j++].id],1); d[q1[i].id]+=(find1(q1[i].y)-find1(q1[i].x-1))*q1[i].r; }j--; while (j>=l) insert1(a[c[j--].id],-1); int num=0; for (i=x;i<=y;i++) if (ans[q[i].id]+d[q[i].id]>=q[i].k) q1[++num]=q[i]; int t=num; for (i=x;i<=y;i++) if (ans[q[i].id]+d[q[i].id]<q[i].k) q1[++num]=q[i],ans[q[i].id]+=d[q[i].id]; for (i=x;i<=y;i++)q[i]=q1[i-x+1],d[q[i].id]=0; sort(c+l,c+mid+1,cmp); dg(l,mid,x,x+t-1);dg(mid+1,r,x+t,y);}int main(){ freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout); scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d",&a[i]),d[i]=d[i-1],insert(1,n,d[i],a[i]); for (i=1;i<=n;i++)scanf("%d",&b[i]),c[i].x=b[i],c[i].id=i; sort(c+1,c+n+1,cmp); scanf("%d",&m); for (i=1;i<=m;i++){ scanf("%d%d%d%d%d",&q[i].l,&q[i].r,&x,&y,&q[i].k);q[i].id=i; t=0;find(1,n,d[q[i].r],d[q[i].l-1],x);q[i].x=t; t=0;find(1,n,d[q[i].r],d[q[i].l-1],y);q[i].y=t; } memset(d,0,sizeof(d)); dg(1,n,1,m); for (i=1;i<=m;i++) printf("%d\n",ans[i]);}
阅读全文
1 0
- 【JZOJ5296】【清华集训2017模拟】Sequence
- 【JZOJ5296】【清华集训模拟】Sequence(整体二分)
- 【清华集训2017模拟】Sequence
- 【清华集训2017模拟】Sequence
- 【JZOJ 5296】【清华集训2017模拟】Sequence
- 5296. 【清华集训2017模拟】Sequence 树套树
- 【清华集训2017模拟】ces
- 【清华集训2017模拟】Catalan
- 【清华集训2017模拟】Create
- [JZOJ5296] Sequence
- 【JZOJ 5295】【清华集训2017模拟】Create
- jzoj5316 【清华集训2017模拟8.19】merge
- 【JZOJ5295】【清华集训2017模拟】Create
- 【JZOJ5316】【清华集训2017模拟8.19】merge
- 【JZOJ5317】【清华集训2017模拟8.19】func
- 【清华集训2017模拟11.26】字符串
- [JZOJ5485]【清华集训2017模拟11.26】字符串
- JZOJ5485. 【清华集训2017模拟11.26】字符串
- USACO 黄金莲花池 BFS
- 机器学习笔记——偏差(bias)和方差(variance)及其与K折交叉验证的关系
- CodeForces
- 如何在Linux下编译安装OpenCV
- 使用VS创建OpenCV工程
- 【JZOJ5296】【清华集训2017模拟】Sequence
- 两串旋转
- Dijkstra算法
- 使RibbonBar中的Button不可用(动态设置CMFCRibbonBar状态)
- ssh开发之登录实现
- Spring Security实践
- 行内元素和块级元素
- 最全oracle单行函数之其他函数用法详解
- 30分钟掌握ES6/ES2015核心内容(上)