整体二分

来源:互联网 发布:美工要学什么软件 编辑:程序博客网 时间:2024/04/26 04:00

相对于普通二分,整体二分用于处理较多询问.如果用普通二分去处理询问,效率将是O(Q*log×f(?))多出来的Q将无法让人承受。因而有了整体二分。整体二分与二分的最大区别就是对所有询问一同处理。所谓的一同处理,是指省去了二分中的冗余部分,上一个询问二分过这个区间,而当前询问又二分了一次,整体二分保证了没有这个冗余。

具体而言,当前带着所有询问传到了一个区间,整理得到一部分询问满足左区间,另一部分满足右区间(废话。。),那么把它们推入两个队列,搞进左右区间继续二分即可。这样就剪掉了时间效率中的Q,使得大量重复的二分被合并。

至于带修改的,明天填坑。
举个很著名的例子:查找区间K大,当然可以用主席树,但有的题并不行。
比如:矩阵乘法.(板子在此OwO)

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#define N 505using namespace std;int n,m,tot,T,zhan[N*600],mark[N*600],ans[N*600],id[N*600],t[N][N];struct node{int x,y,h;}a[N*N];struct QQQ{int l1,l2,r1,r2,k;}q[N*600];void add(int x,int y,int k){    for(int i=x;i<=n;i+=i&-i)        for(int j=y;j<=n;j+=j&-j)            t[i][j]+=k;}int q1(int x,int y){    int s=0;    for(int i=x;i>0;i-=i&-i)        for(int j=y;j>0;j-=j&-j)            s+=t[i][j];    return s;}int Q(int k){    int l1=q[k].l1,l2=q[k].l2,r1=q[k].r1,r2=q[k].r2;    return q1(l2,r2)+q1(l1-1,r1-1)-q1(l1-1,r2)-q1(l2,r1-1);}//套二维树状数组inline bool cmp(node a,node b){return a.h<b.h;}void work(int l,int r,int L,int R){    if(L==R||l>r)return;    int mid=L+R>>1;    while(a[T+1].h<=mid&&T<tot){add(a[T+1].x,a[T+1].y,1);T++;}    while(a[T].h>mid){add(a[T].x,a[T].y,-1);T--;}    int sum=0;    for(int i=l;i<=r;i++)    {        if(Q(id[i])>q[id[i]].k-1)        {            mark[i]=1;ans[id[i]]=mid;sum++;        }        else mark[i]=0;    }    int l1=l,l2=l+sum;    for(int i=l;i<=r;i++)        if(mark[i])zhan[l1++]=id[i];        else zhan[l2++]=id[i];    for(int i=l;i<=r;i++)id[i]=zhan[i];    work(l,l1-1,L,mid);work(l1,l2-1,mid+1,R);}int main(){    scanf("%d%d",&n,&m);int mm=0;    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        {            scanf("%d",&a[++tot].h);            a[tot].x=i;a[tot].y=j;            mm=max(mm,a[tot].h);        }    sort(a+1,a+tot+1,cmp);    for(int i=1;i<=m;i++)scanf("%d%d%d%d%d",&q[i].l1,&q[i].r1,&q[i].l2,&q[i].r2,&q[i].k);    for(int i=1;i<=m;i++)id[i]=i;    work(1,m,0,mm+1);    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);}
原创粉丝点击