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

    题解:  整体二分模板题  整体二分与CDQ的思想类似 我们考虑到二分答案 然后对于查询的区间 我们考虑到当前的贡献与期望贡献的关系 然后分治查询即可

    #include <bits/stdc++.h>
    const int inf=1e9;
    using namespace std;
    typedef struct node{
    	int x,y,x1,y1,k;int ans,cnt;
    }node;
    node que[60005];
    typedef struct Node{
    	int x,y,vul;
    	friend bool operator<(Node aa,Node bb){return aa.vul<bb.vul;}
    }Node;
    Node a[300005];
    int d[505][505],sz,n,m;
    int get_id(int x){return x&(-x);}
    void add(int x,int y,int vul){
    	for(int i=x;i<=n;i+=get_id(i)){
    		for(int j=y;j<=n;j+=get_id(j))d[i][j]+=vul;
    	}
    }
    int Sum(int x,int y){
    	int sum1=0;
    	for(int i=x;i>0;i-=get_id(i)){
    		for(int j=y;j>0;j-=get_id(j))sum1+=d[i][j];
    	}
    	return sum1;
    }
    int querty(int pos){return Sum(que[pos].x1,que[pos].y1)+Sum(que[pos].x-1,que[pos].y-1)-Sum(que[pos].x-1,que[pos].y1)-Sum(que[pos].x1,que[pos].y-1);}
    int tot,id[60005],ed[60005],ip[60005];
    void slove(int ql,int qr,int l,int r){
    	if(ql>qr||l==r)return ;
    	int mid=(l+r)>>1;
    	//cout<<l<<" "<<r<<endl;
    	while(tot<sz&&a[tot+1].vul<=mid){
    		tot++;
    		add(a[tot].x,a[tot].y,1);
    	}
    	while(tot&&a[tot].vul>mid){
    		add(a[tot].x,a[tot].y,-1);
    		tot--;
    	}int cnt=0,cnt1=0;
    	//cout<<tot<<"===="<<mid<<" "<<ql<<" "<<qr<<" "<<que[id[1]].cnt<<endl;
    	for(int i=ql;i<=qr;i++){
    		if(querty(id[i])>=que[id[i]].k)ed[++cnt]=id[i],que[id[i]].ans=mid;
    		else ip[++cnt1]=id[i];
    	}
    	for(int i=1;i<=cnt;i++)id[ql+i-1]=ed[i];
    	for(int i=1;i<=cnt1;i++)id[ql+cnt+i-1]=ip[i];
    	slove(ql,ql+cnt-1,l,mid);
    	slove(ql+cnt,qr,mid+1,r);
    }
    int main(){
    	scanf("%d%d",&n,&m);sz=n*n;
    	int vul;tot=0;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			scanf("%d",&vul);a[(i-1)*n+j]=(Node){i,j,vul};
    		}
    	}
    	sort(a+1,a+sz+1);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d%d%d",&que[i].x,&que[i].y,&que[i].x1,&que[i].y1,&que[i].k);
    		que[i].ans=que[i].cnt=0;id[i]=i;
    	}
    	slove(1,m,0,inf);
    	for(int i=1;i<=m;i++)printf("%d
    ",que[i].ans);
    	return 0;
    }
    

    2738: 矩阵乘法

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 1951  Solved: 855
    [Submit][Status][Discuss]

    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。

     

  • 相关阅读:
    rest framework 认证 权限 频率
    rest framework 视图,路由
    rest framework 序列化
    10.3 Vue 路由系统
    10.4 Vue 父子传值
    10.2 Vue 环境安装
    10.1 ES6 的新增特性以及简单语法
    Django 跨域请求处理
    20190827 On Java8 第十四章 流式编程
    20190825 On Java8 第十三章 函数式编程
  • 原文地址:https://www.cnblogs.com/wang9897/p/9462801.html
Copyright © 2011-2022 走看看