zoukankan      html  css  js  c++  java
  • 前缀和

    前缀和这种小技巧noip很容易就考到了,例如11年的聪明的质监员这道题二分但是用到了前缀和优化。前缀和可以优化一下时间复杂度。

    首先是一维的前缀和,a[i]+=a[i-1];这样很简单使用的时候只要直接a[r]-a[l-1]就可以吧r到l直接的累加全部搞出来优化一重循环0.0;

    下面是10.21考的普及组的一道题,一眼看出是个二维的前缀和,但下手的时候由于时间不充足还是选择打了暴力结果GG。

    范围n,m<=300,显然二维的前缀和只要数出0和1的个数即可,不会啊~~~。

    这个要怎么求呢?很显然当前的值a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1]即可这样前缀和就解决了,但是如何调用也是一个问题。

    当前是要求每个小矩阵的0和1所以当前的点是向外延伸k的长度的所以可设当前点为i,j矩阵右下方的端点为w=i+k-1,y=j+k-1(注意细节),那么只要求出来从w,y到i,j直接的0和1的个数即可。自己画个图易知当前前缀和=a[w][y]-a[w][j-1]+a[i-1][y]+a[i-1][j-1].这样问题就被完美的解决了,这道题有很多的细节,码力不好的话很容易就wa掉。。。见代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<vector>
    #include<map>
    #include<queue>
    #include<iomanip>
    #include<stack>
    #include<algorithm>
    using namespace std;
    inline long long read()
    {
        long long x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const long long maxn=1000;
    long long n,m;
    long long a[maxn][maxn],ans=0,ans1=0,tot=0,s;
    struct bwy{long long x,y;}b[maxn][maxn];
    int main()
    {
        //freopen("paint.in","r",stdin);
        //freopen("paint.out","w",stdout);
        //freopen("1.in","r",stdin);
        n=read();m=read();s=min(n,m);
        for(long long i=1;i<=n;i++)
        {
            for(long long j=1;j<=m;j++)
            {    
                a[i][j]=read();
                if(a[i][j]==1)
                {
                    b[i][j].x++;
                    b[i][j].x+=b[i][j-1].x;
                    b[i][j].x+=b[i-1][j].x-b[i-1][j-1].x;
                    b[i][j].y+=b[i][j-1].y;
                    b[i][j].y+=b[i-1][j].y-b[i-1][j-1].y;
                }
                else
                {
                    b[i][j].y++;
                    b[i][j].x+=b[i][j-1].x;
                    b[i][j].x+=b[i-1][j].x-b[i-1][j-1].x;
                    b[i][j].y+=b[i][j-1].y;
                    b[i][j].y+=b[i-1][j].y-b[i-1][j-1].y;
                }
            }    
        }
        //for(long long i=1;i<=n;i++){for(long long j=1;j<=m;j++){printf("%d ",b[i][j].x);}printf("
    ");}
        for(long long k=2;k<=s;k++)
        for(long long i=1;i<=n-k+1;i++)
        {
            for(long long j=1;j<=m-k+1;j++)
            {
                long long w=i+k-1,y=j+k-1;
                if(abs((b[w][y].x+b[i-1][j-1].x-b[w][j-1].x-b[i-1][y].x)-(b[w][y].y+b[i-1][j-1].y-b[w][j-1].y-b[i-1][y].y))<=1)
                    tot++;
            }
        }
        printf("%lld
    ",tot);
        return    0;
    }
    View Code

    此其所挟持者甚大,而其志甚远也。

  • 相关阅读:
    HDU 1025 Constructing Roads In JGShining's Kingdom (DP+二分)
    HDU 1158 Employment Planning
    HDU 2059 龟兔赛跑
    Csharp 简单操作Word模板文件
    Csharp windowform datagridview Clipboard TO EXCEL OR FROM EXCEL DATA 保存datagridview所有數據
    Csharp 讀寫文件內容搜索自動彈出 AutoCompleteMode
    Csharp windowform controls clear
    CSS DIV大图片右上角叠加小图片
    Csharp DataGridView自定义添加DateTimePicker控件日期列
    Csharp 打印Word文件默認打印機或選擇打印機設置代碼
  • 原文地址:https://www.cnblogs.com/chdy/p/9832441.html
Copyright © 2011-2022 走看看