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;
    }
    
  • 相关阅读:
    WPF之触发器
    WP之样式
    SqlServer2012——多表连接查询
    SqlServer2012——Select,分组,排序、插入
    sqlserver——视图
    SqlServer规则
    SqlServer自定义数据类型
    SqlServer2012——表
    ES基础使用
    ELK安装
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366410.html
Copyright © 2011-2022 走看看