zoukankan      html  css  js  c++  java
  • 【华东师附国庆模拟赛】Day2 1.矩阵

    题目链接

    在这里%一波$mathscr{ZMY}$搭题目。

    题意:

      给定$n imes n$的矩阵$A$,$B$,$m$次询问,求$C=A imes B$的子矩阵和。

      $1le nle 800,; 1le mle 10^4,; 0le A_{i,j}le 100$

    分析:

      设询问子矩阵为$[i_1:i_2][j_1:j_2]$,则

      $quadsumlimits_{i=i_1}^{i_2}sumlimits_{j=j_1}^{j_2}sumlimits_{k=1}^{n}A[i][k] imes B[k][j]$

      $=sumlimits_{k=1}^{n}sumlimits_{i=i_1}^{i_2}A[i][k]sumlimits_{j=j_1}^{j_2}B[k][j]$

      $=sumlimits_{k=1}^{n}A[i_1:i_2][k] imes B[k][j_1:j_2]$

      于是$O(n^2)$预处理$A$每列的前缀和,$B$每行的前缀和,$O(n)$询问。

    实现(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define IL inline
    #define UI unsigned int
    #define RI register int
    using namespace std;
    typedef long long LL;
    const int N=800;
    
    IL void read(int &x){
        char ch;
        while(!isdigit(ch=getchar()));
        x=ch-'0';
        while(isdigit(ch=getchar()))
            x=(x<<3)+(x<<1)+ch-'0';
    }
    
    IL void read(int &x,int &y){
        read(x);    read(y);
    }
    
    IL void read(int &x,int &y,int &p,int &q){
        read(x);    read(y);    read(p);    read(q);
    }
    
    IL void read(LL &x){
        char ch;
        while(!isdigit(ch=getchar()));
        x=ch-'0';
        while(isdigit(ch=getchar()))
            x=(x<<3LL)+(x<<1LL)+ch-'0';
    }
    
        int n,m;
        LL a[N+3][N+3],b[N+3][N+3];
        LL s1[N+3][N+3],s2[N+3][N+3];
        
    IL LL sum1(int i1,int i2,int k){
        return s1[i2][k]-s1[i1-1][k];
    }
    
    IL LL sum2(int k,int j1,int j2){
        return s2[k][j2]-s2[k][j1-1];
    }
    
    int main(){
        read(n,m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                read(a[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                read(b[i][j]);
        
        memset(s1,0,sizeof s1);
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                s1[i][k]=s1[i-1][k]+a[i][k];
        memset(s2,0,sizeof s2);
        for(int k=1;k<=n;k++)
            for(int j=1;j<=n;j++)
                s2[k][j]=s2[k][j-1]+b[k][j];
        
        while(m--){
            int p1,p2,p3,p4;    read(p1,p2,p3,p4);
            if(p1>p3)swap(p1,p3);
            if(p2>p4)swap(p2,p4);
            
            LL ans=0;
            for(int k=1;k<=n;k++)
                ans+=sum1(p1,p3,k)*sum2(k,p2,p4);
            printf("%lld
    ",ans);
            
        }
    
        return 0;
    
    }
    View Code

    小结:

      快速推式子上手。

  • 相关阅读:
    Python中的字典
    Python中的元组
    Python中常见的公共方法
    Python中的列表
    Python的循环语句
    Python的流程控制
    Kubernetes-kubectl命令出现错误【The connection to the server localhost:8080 was refused
    nyoj 77-开灯问题 (倍数遍历)
    nyoj 76-超级台阶 (递推)
    nyoj 75-日期计算 (闰年与平年的判断)
  • 原文地址:https://www.cnblogs.com/Hansue/p/11683310.html
Copyright © 2011-2022 走看看