zoukankan      html  css  js  c++  java
  • 整体二分

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

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

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

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #define N 505
    using 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
    ",ans[i]);
    }
  • 相关阅读:
    C# Asp.net中简单操作MongoDB数据库(二)
    Windows下使用TeamViewer连接远程服务器,以及解决“远程桌面关闭后TeamViewer不能连接”的问题
    存储过程
    C# 使用MongoDB遇到的问题
    C# Asp.net中简单操作MongoDB数据库(一)
    Windows下MongoDB设置用户、密码
    退役狗也要搬博客
    codeforces840E In a Trap
    uoj207共价大爷游长沙
    bzoj2662: [BeiJing wc2012]冻结 最短路 建图
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632638.html
Copyright © 2011-2022 走看看