• [BZOJ2738]矩阵乘法-[整体二分+树状数组]


    Description

    给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。

    (N<=500,Q<=60000)

    Solution

    考虑二分答案,问题转化为求矩阵内为1的点数,可以用二维树状数组。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct P{int num,x,y;}a[250010];int cnt_a=0;
    bool cmp(P x,P y){return x.num<y.num;}
    int rk[100100],all=0;
    
    int n,m;
    struct node{int x,y,xx,yy,k,id;
    }q[60010],st[2][60010];int ans[60010];
    
    int tree[510][510];
    void add(int x,int y,int data){for(;x<=n;x+=x&-x)for(int j=y;j<=n;j+=j&-j) tree[x][j]+=data;}
    int query(int x,int y){int re=0;for(;x;x-=x&-x)for(int j=y;j;j-=j&-j) re+=tree[x][j];return re;}
    int now;
    void solve(int ql,int qr,int ansl,int ansr)
    {
        if (ql>qr) return;
        if (ansl==ansr) 
        {
            for (int i=ql;i<=qr;i++) ans[q[i].id]=ansl;
            return;
        }
        int ansmid=ansl+ansr>>1,cnt,js0=0,js1=0;
        for (;now<ansmid;) now++,add(a[now].x,a[now].y,1);
        for(;now>ansmid;now--) add(a[now].x,a[now].y,-1);
        for (int i=ql;i<=qr;i++)
        {
            cnt=query(q[i].xx,q[i].yy)+query(q[i].x-1,q[i].y-1)-query(q[i].x-1,q[i].yy)-query(q[i].xx,q[i].y-1);
            if (cnt>=q[i].k) st[0][++js0]=q[i];
            else st[1][++js1]=q[i];
        }
        for (int i=1;i<=js0;i++) q[i+ql-1]=st[0][i];
        for (int i=1;i<=js1;i++) q[i+ql+js0-1]=st[1][i];
        solve(ql,ql+js0-1,ansl,ansmid);
        solve(ql+js0,qr,ansmid+1,ansr);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)
        {
            scanf("%d",&a[++cnt_a].num);a[cnt_a].x=i;a[cnt_a].y=j;
        }
        sort(a+1,a+cnt_a+1,cmp);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d%d",&q[i].x,&q[i].y,&q[i].xx,&q[i].yy,&q[i].k);q[i].id=i;
        }
        solve(1,m,0,n*n);
        for (int i=1;i<=m;i++) printf("%d
    ",a[ans[i]].num);
        
    }

     

  • 相关阅读:
    学习方法:费曼学习方法
    学习方法:天才的秘密
    学习方法:学习的大致过程
    OS:VM虚拟机连不上网络
    cpp:argc和argv的应用
    baidu:{{!!}}
    os:windows许可证书位置
    书法:练字的心得体会
    修复Python终端中敲击方向键显示 [ ^[[A, ^[[B, ^[[C, ^[[D ]
    jquery下removeClass(“oldClassName”).addClass("newClassName")的问题
  • 原文地址:https://www.cnblogs.com/coco-night/p/9495328.html
Copyright © 2020-2023  润新知