zoukankan      html  css  js  c++  java
  • BZOJ118——激光炸弹(二维前缀和)

    二维前缀和

    题意:给你一个5000*5000的格子,有些格子里面有值,询问一个rrr*r的正方形的最大值

    由于数据范围是5000,刚好不需要离散化,直接预处理出二维前缀和,利用差分O(1)查询每个正方形,复杂度O(n2)O(n^2)

    二维前缀和写法有很多,主要是两种

    for(i=1;i<=5001;i++)
        		for(j=1;j<=5001;j++) a[i][j]+=a[i-1][j];
    for(i=1;i<=5001;i++)
        		for(j=1;j<=5001;j++) a[i][j]+=a[i][j-1];
    

    	for(int i=1;i<=5001;i++){
    	    	for(int j=1;j<=5001;j++){
    	        		a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        		}
    	}
    

    然后每次询问的时候利用容斥原理做一下

    比如一个以(i,j)(i,j)为右上角,(ir,jr)(i-r,j-r)为左下角的矩阵的值为t[i][j]t[i][jr]t[ir][j]+t[ir][jr]t[i][j]-t[i][j-r]-t[i-r][j]+t[i-r][j-r]

    可以自己画图手推一下

    代码

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    const int N=5005;
    int t[N][N],m,n,r;
    int main(){
        n=read(),r=read();
        for(int i=1;i<=n;i++){
            int x=read(),y=read(),a=read();
            t[x+1][y+1]+=a;
        }
        for(int i=1;i<=5001;i++){
            for(int j=1;j<=5001;j++){
                a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
            }
        }
        int ans=0;
        for(int i=r;i<=5001;i++){
            for(int j=r;j<=5001;j++){
                ans=max(ans,t[i][j]-t[i][j-r]-t[i-r][j]+t[i-r][j-r]);
            }
        }
        cout<<ans;
    }
    
  • 相关阅读:
    取近似值
    eclipse 自己主动为getter和setter加入中文凝视
    Linux对外连接port数限制
    C++链表冒泡,归并,插入排序(纯指针)
    Android之实现ViewPager+Fragment左右滑动
    获得鼠标离开消息。
    CMFCPropertyGridProperty的使用
    阅读书单
    Docker 容器管理
    docker rmi 详解
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366410.html
Copyright © 2011-2022 走看看