zoukankan      html  css  js  c++  java
  • Bzoj2738 矩阵乘法

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 1471  Solved: 632

    Description

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

    Input

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

    Output

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

    Sample Input

    2 2
    2 1
    3 4
    1 2 1 2 1
    1 1 2 2 3

    Sample Output

    1
    3

    HINT

      矩阵中数字是109以内的非负整数;

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

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

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

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

    Source

    分治 整体二分

    二分一个答案,然后处理所有询问,把答案小于当前尝试值的和大于当前值的询问分别递归处理。

    54行的保护机制似乎并没有什么用,一定要像74和76行那样加上if判断才能防止爆炸,迷。

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 using namespace std;
      9 const int mxn=510;
     10 int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 struct num{
     17     int x,y,w;
     18     bool operator < (const num b)const{
     19         return w<b.w;
     20     }
     21 }a[mxn*mxn];
     22 int t[mxn][mxn];
     23 int n;
     24 void add(int x,int y,int v){
     25     while(x<=n){
     26         int tmp=y;
     27         while(tmp<=n){t[x][tmp]+=v; tmp+=tmp&-tmp;}
     28         x+=x&-x;
     29     }
     30     return;
     31 }
     32 int smm(int x,int y){
     33     int res=0;
     34     while(x){
     35         int tmp=y;
     36         while(tmp){res+=t[x][tmp]; tmp-=tmp&-tmp;}
     37         x-=x&-x;
     38     }
     39     return res;
     40 }
     41 inline int ask(int x1,int y1,int x2,int y2){
     42     return smm(x2,y2)-smm(x1-1,y2)-smm(x2,y1-1)+smm(x1-1,y1-1);
     43 }
     44 struct query{
     45     int x1,y1,x2,y2;
     46     int k,id;
     47 }q[mxn*120];
     48 int now[mxn*120],tmp[mxn*120];
     49 int ans[mxn*120];
     50 int Q,ed;
     51 void solve(int l,int r,int L,int R){//答案区间,询问区间 
     52 //    printf("l:%d r:%d L:%d R:%d
    ",l,r,L,R);
     53     if(l>r || L>R)return;
     54 //    if(l==r)return;
     55     int mid=(a[l].w+a[r].w)>>1;
     56     int i,j,cnt=0;
     57     for(i=l;i<=r && a[i].w<=mid;i++){add(a[i].x,a[i].y,1);++cnt;}
     58     int el=L-1,er=R+1,c;
     59     for(i=L;i<=R;i++){
     60         c=now[i];
     61         int res=ask(q[c].x1,q[c].y1,q[c].x2,q[c].y2);
     62         if(res>=q[c].k){
     63             ans[q[c].id]=mid;
     64             tmp[++el]=c;
     65         }
     66         else{//res<q[c].k
     67             tmp[--er]=c;
     68             q[c].k-=res;
     69         }
     70     }
     71     for(i=l;i<=r && a[i].w<=mid;i++){add(a[i].x,a[i].y,-1);}
     72     for(i=L;i<=R;i++){now[i]=tmp[i];}
     73 //    if(l+cnt-1!=r || el!=R)solve(l,l+cnt-1,L,el);
     74     if(l+cnt-1!=r || el!=R)solve(l,l+cnt-1,L,el);
     75 //    if(l+cnt!=l || er!=L) solve(l+cnt,r,er,R);
     76     if(l+cnt!=l || er!=L) solve(l+cnt,r,er,R);
     77     return;
     78 }
     79 int tct=0;
     80 int main(){
     81 //    freopen("in.txt","r",stdin);
     82     int i,j,x;
     83     n=read();Q=read();
     84     ed=n*n;
     85     for(i=1;i<=n;i++)
     86         for(j=1;j<=n;j++){
     87             a[++tct].x=i; a[tct].y=j;
     88             a[tct].w=read();
     89         }
     90     sort(a+1,a+ed+1);
     91     for(i=1;i<=Q;i++){
     92         q[i].x1=read();    q[i].y1=read();
     93         q[i].x2=read();    q[i].y2=read();
     94         q[i].k=read();  q[i].id=i;
     95         now[i]=i;
     96     }
     97     solve(1,ed,1,Q);
     98     for(i=1;i<=Q;i++)printf("%d
    ",ans[i]);
     99     return 0;
    100 }
  • 相关阅读:
    随手练——几个递归小题目
    随手练——USACO 1.44 母亲的牛奶
    随手练——汉诺塔问题(递归典型)
    Linux搭建lamp(Apache+PHP+Mysql环境)centos7.2版详细教程
    Windows 环境下安装redis 及其PHP Redis扩展
    Windows系统如何安装Redis
    phpstorm配置成sublime的代码高亮逼格风格
    phpstorm-----实现实时编辑服务器代码
    如何在Webstorm/Phpstorm中设置连接FTP,并快速进行文件比较,上传下载,同步等操作
    phpstorm取消自动保存,修改快捷键并标识修改的文件为星星标记
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6588850.html
Copyright © 2011-2022 走看看