双指针优化二维前缀和

先看例题https://www.luogu.com.cn/problem/P8783

由题意可以快速写出一个\(n^4\)复杂度的二维前缀和,如下

 for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int x=i;x<=n;x++){
                for(int y=j;y<=m;y++){
                    int t=(pre[x][y]-pre[x][j-1]-pre[i-1][y]+pre[i-1][j-1]);
                    if(t<=k){
                        ans++;
                    }
                }
            }
        }
    }

但是根据题目中\(n \le 500\)的范围来看,显然是无法拿满分的,因此可以换一种枚举思路,即利用双指针维护一个矩阵的左上点与右下点,当某一个范围内的答案再也无法满足题意时统计答案,可以将时间复杂度优化到接近\(O(n^3)\)

for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            //(i,l)可以视为左上角点,(j,r)为右下角点
            for(int l=1,r=1;r<=m;r++){
                while(l<=r and pre[j][r]-pre[i-1][r]-pre[j][l-1]+pre[i-1][l-1]>k) l++; // 枚举右下角点 
                ans+=(r-l+1);
            }
        }
    }

posted on 2025-02-19 19:52  TaopiTTT  阅读(43)  评论(0)    收藏  举报