【JZOJ5296】【清华集训模拟】Sequence(整体二分)
来源:互联网 发布:极客学院java百度网盘 编辑:程序博客网 时间:2024/06/10 21:18
Description
Solution
这是第一次打整体二分。是一道十分裸的整体二分。
整体二分大致思想就是,对于一坨询问,我们二分一个值,然后对所有的询问都进行判断,然后分别放到[l,mid]和[mid+1,r],这要每次枚举的区间都是[l,r]的话,时间复杂度就是log的。
首先排名[x,y]的可以用主席树来搞出它的值域范围。
我们对于b的答案二分一个值mid。然后找到所有b的值小于mid(这个可以对一开始的数组排个序,然后选择的区间都是连续的一段,因为是个排列,新加入的连续一段[l,mid])。然后我们用树状数组统计一下在值域内的个数是否小于等于k(这个就是一个二维偏序),然后在判断哪些个数是小于等于它的k的,是就往[l,mid]走,否则[mid+1,r]。树状数组的清空直接把所有用过的数再倒着做一次,就是-1。
时间复杂度O(nlog^2)
Code
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=2e5+7;int i,j,k,l,n,m,ans,an[maxn],o,kk[maxn],xx[maxn],yy[maxn],d[maxn],hhh;struct node{ int l,r,c,o;}c[maxn],g[maxn],q[maxn];bool cmp(node x,node y){return x.r<y.r;}bool cmp1(node x,node y){return x.r<y.r;}struct nod{ int l,r,sum;}tt[maxn*40];int a[maxn],b[maxn],root[maxn],num,t[maxn],tot,tmp,e[maxn],f[maxn];void insert(int &x,int y,int l,int r,int z){ x=++num;tt[x]=tt[y]; if(l==r){tt[x].sum++;return;} int mid=(l+r)/2; if(z<=mid)insert(tt[x].l,tt[y].l,l,mid,z); else insert(tt[x].r,tt[y].r,mid+1,r,z); tt[x].sum=tt[tt[x].l].sum+tt[tt[x].r].sum;}int find1(int x,int y,int l,int r,int k){ if(l==r)return l; int mid=(l+r)/2; if(tt[tt[x].l].sum-tt[tt[y].l].sum>=k)return find1(tt[x].l,tt[y].l,l,mid,k); else return find1(tt[x].r,tt[y].r,mid+1,r,k-tt[tt[x].l].sum+tt[tt[y].l].sum);}void add(int x,int y){ for(;x<=n;x+=(x&-x))t[x]+=y;}int find(int x){ int z=0;if(!x)return 0; for(;x;x-=(x&-x))z+=t[x]; return z;}void solve(int l,int r,int l1,int r1){ int i,j,mid; if(l>r)return; if(l1==r1){ fo(i,l,r)an[c[i].c]=l1; return; } mid=(l1+r1)/2; fo(i,l1,mid)d[i]=q[i].c;sort(d+l1,d+mid+1); o=0;fo(i,l,r)g[++o]=c[i],g[o].o=1,g[++o]=c[i],g[o].o=-1,g[o].r=g[o].l-1,f[c[i].c]=e[c[i].c]; sort(g+1,g+1+o,cmp); j=1; fo(i,l1,mid){ while(j<=o&&g[j].r<d[i]) e[g[j].c]+=(find(yy[g[j].c])-find(xx[g[j].c]-1))*g[j].o,j++; if(a[d[i]]==0){ ans=ans; } add(a[d[i]],1); } while(j<=o)e[g[j].c]+=(find(yy[g[j].c])-find(xx[g[j].c]-1))*g[j].o,j++; fo(i,l1,mid)add(a[d[i]],-1); tmp=l-1; fo(i,l,r){ if(e[c[i].c]>=kk[c[i].c])g[++tmp]=c[i]; } int u=tmp; fo(i,l,r)if(e[c[i].c]<kk[c[i].c])g[++tmp]=c[i];else e[c[i].c]=f[c[i].c]; fo(i,l,r){ c[i]=g[i]; } solve(l,u,l1,mid); solve(u+1,r,mid+1,r1);}int main(){ freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]),insert(root[i],root[i-1],1,n,a[i]); fo(i,1,n)scanf("%d",&b[i]),q[i].l=a[i],q[i].r=b[i],q[i].c=i; sort(q+1,q+1+n,cmp1); scanf("%d",&m); fo(i,1,m){ scanf("%d%d%d%d%d",&c[i].l,&c[i].r,&xx[i],&yy[i],&kk[i]);c[i].c=i; xx[i]=find1(root[c[i].r],root[c[i].l-1],1,n,xx[i]); yy[i]=find1(root[c[i].r],root[c[i].l-1],1,n,yy[i]); } solve(1,m,1,n); fo(i,1,m)printf("%d\n",an[i]);}
阅读全文
1 0
- 【JZOJ5296】【清华集训模拟】Sequence(整体二分)
- 【JZOJ5296】【清华集训2017模拟】Sequence
- 【清华集训2017模拟】Sequence
- 【清华集训2017模拟】Sequence
- 【JZOJ 5296】【清华集训2017模拟】Sequence
- 5296. 【清华集训2017模拟】Sequence 树套树
- [JZOJ5296] Sequence
- 【清华集训2017模拟】ces
- 【清华集训2017模拟】Catalan
- 【清华集训2017模拟】Create
- jzoj5317 【清华集训2017模拟8.19】func (寻找性质)
- 【JZOJ5295】【清华集训模拟】Create(主席树)
- 【JZOJ5316】【清华集训模拟】merge(DP、括号序)
- 【JZOJ 5295】【清华集训2017模拟】Create
- jzoj5316 【清华集训2017模拟8.19】merge
- 【JZOJ5295】【清华集训2017模拟】Create
- 【JZOJ5316】【清华集训2017模拟8.19】merge
- 【JZOJ5317】【清华集训2017模拟8.19】func
- 【服务器】java.lang.OutOfMemoryError
- 布局随笔
- JAVA操作HBASE数据操作详解
- Java中的Filter过滤器
- 算法导论习题自作2.1-2
- 【JZOJ5296】【清华集训模拟】Sequence(整体二分)
- HDU 1690 Bus System(Floyd)
- 浅谈对handle的理解
- ZigBee CC2530 Z-Stack 19 单播通信2-64位地址模式
- CDN是什么?使用CDN有什么优势?
- URL、SRC、href之间的区别
- scala隐式转换函数
- Docker安装Nginx环境
- 进程间通信的方式