• 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。

     

  • 相关阅读:
    JavaScript之DOM查询
    JavaScript之this解析
    Qt之pro文件解析
    Qt5 调试之详细日志文件输出(qInstallMessageHandler)
    修改 Ubuntu的源为阿里源
    Unable to acquire the dpkg frontend lock
    gcc编译中文字符串后,windows控制台输出乱码
    stm32f103 time2配置,转载
    取反
    单片机,struct ,union定义标志,节约RAM
  • 原文地址:https://www.cnblogs.com/wang9897/p/9462801.html
Copyright © 2020-2023  润新知