• 整体二分



    P1527 [国家集训队]矩阵乘法

    题目描述

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

    输入格式

    第一行两个数N,Q,表示矩阵大小和询问组数;

    接下来N行N列一共N*N个数,表示这个矩阵;

    再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。

    输出格式

    对于每组询问输出第K小的数。

    输入输出样例

    输入 #1
    2 2
    2 1
    3 4
    1 2 1 2 1
    1 1 2 2 3
    输出 #1
    1
    3

    说明/提示

    矩阵中数字是10^9以内的非负整数;

    20%的数据:N<=100,Q<=1000;

    40%的数据:N<=300,Q<=10000;

    60%的数据:N<=400,Q<=30000;

    100%的数据:N<=500,Q<=60000。

         

     1 #include<bits/stdc++.h>
     2 #define re register int
     3 #define maxn 500+5
     4 #define maxn1 60000+5
     5 #define maxn2 250000+5
     6 
     7 using namespace std;
     8 int n,q;
     9 int  ans[maxn1],id[maxn1]; 
    10 int sum[maxn1];
    11 int tree[maxn][maxn];
    12 int tmp1[maxn1],tmp2[maxn1];
    13 struct matr{
    14     int x,y,val;
    15 }ma[maxn2];
    16 struct  query{
    17     int lx,ly,rx,ry,k;
    18 }qu[maxn1];
    19 int cnt,tmp;
    20 bool cmp(const matr&a,const matr&b)
    21 {
    22     return a.val<b.val;
    23 }
    24 int lowbit(int x)
    25 {
    26     return x&-x;
    27 }
    28 void add(int x,int y,int val)
    29 {
    30     for(re i=x;i<=n;i+=lowbit(i))
    31     for(re j=y;j<=n;j+=lowbit(j))
    32     tree[i][j]+=val; 
    33 }
    34 int cal(int x,int y)
    35 {
    36    int res=0;
    37    for(re i=x;i;i-=lowbit(i))
    38    for(re j=y;j;j-=lowbit(j))//233333不要写j>=0 
    39    res+=tree[i][j];
    40    return res;
    41 }
    42 int sol(int lx1,int ly1,int rx1,int ry1)
    43 {
    44     return cal(rx1,ry1)-cal(lx1-1,ry1)-cal(rx1,ly1-1)+cal(lx1-1,ly1-1);
    45 }
    46 void dic(int l,int r,int ql,int qr)
    47 {
    48     if(ql>qr) return;
    49     if(l==r)
    50     {
    51         for(re i=ql;i<=qr;i++)
    52         ans[id[i]]=ma[l].val;
    53         return;
    54     }
    55     int mid=(l+r)>>1;
    56     int cnt1=0,cnt2=0;
    57     for(re i=l;i<=mid;i++)
    58     add(ma[i].x,ma[i].y,1);//从l加上<=mid的数,l之前都已经加入sum数组 
    59     for(re i=ql;i<=qr;i++)
    60     {
    61         tmp=sol(qu[id[i]].lx,qu[id[i]].ly,qu[id[i]].rx,qu[id[i]].ry);
    62         if(tmp+sum[id[i]]>=qu[id[i]].k) tmp1[++cnt1]=id[i];
    63         else sum[id[i]]+=tmp,tmp2[++cnt2]=id[i];
    64     }
    65     for(re i=l;i<=mid;i++)
    66     add(ma[i].x,ma[i].y,-1);
    67     int tmp3=ql-1;
    68     for(re i=1;i<=cnt1;i++)
    69     id[++tmp3]=tmp1[i];
    70     for(re i=1;i<=cnt2;i++)
    71     id[++tmp3]=tmp2[i];
    72     dic(l,mid,ql,ql+cnt1-1);
    73     dic(mid+1,r,ql+cnt1,qr);
    74     }
    75 int main()
    76 {
    77     ios::sync_with_stdio(false);
    78     cin>>n>>q;
    79     for(re i=1;i<=n;i++)
    80     for(re j=1;j<=n;j++)
    81     {
    82         cin>>tmp;
    83         ma[++cnt].x=i;
    84         ma[cnt].y=j;
    85         ma[cnt].val=tmp;
    86     //毒瘤的坐标存法 
    87     }
    88     sort(ma+1,ma+cnt+1,cmp);
    89     for(re i=1;i<=q;i++)
    90     cin>>qu[i].lx>>qu[i].ly>>qu[i].rx>>qu[i].ry>>qu[i].k,id[i]=i;
    91     dic(1,cnt,1,q);
    92     for(re i=1;i<=q;i++)
    93     cout<<ans[i]<<endl;//是ans[i]不是ans[id] 
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    [PyTorch 学习笔记] 8.1 图像分类简述与 ResNet 源码分析
    [PyTorch 学习笔记] 7.3 使用 GPU 训练模型
    [PyTorch 学习笔记] 7.2 模型 Finetune
    [PyTorch 学习笔记] 7.1 模型保存与加载
    [PyTorch 学习笔记] 6.2 Normalization
    【成都GamEver游戏公司诚邀服务器伙伴】【7~15k一年4次项目奖金】
    如何彻底隐藏iOS7应用的status bar
    更新证书错误Code Sign error: Provisioning profile ‘XXXX'can't be found
    leetcode@ [273] Integer to English Words (String & Math)
    geeksforgeeks@ Largest Number formed from an Array
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11598133.html
Copyright © 2020-2023  润新知