zoukankan      html  css  js  c++  java
  • 洛谷P3941 入阵曲

    题目链接

    入阵曲

    solution

    • 很容易想到预处理二维前缀和%k的余数,然后\(O(n^4)\)判断
    • 考虑如何优化到\(O(n^3)\)
    • 我们可以枚举子矩形的起点的\(x\)坐标与水平长度,于是问题就可转化为一维
    • 在一维平面上,一个子矩阵的和可以转化为一个大的前缀矩阵和减去一个小的,显然只要这2个矩阵和%k的余数相同,对应的子矩阵就符合条件
    • 于是可以\(O(n)\)扫一遍记录%k余\(i\)的前缀矩阵和有多少个,即可\(O(n^3)\)完成

    code

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*f;
    }
    typedef long long ll;
    const int N=450;
    const int K=1e6+10;
    int n,m,k,a[N][N],s[N][N],w[K];
    ll ans;
    inline int add(int x,int y){return (x+y>=k)?x+y-k:x+y;}
    inline int dec(int x,int y){return (x-y<0)?x-y+k:x-y;}
    int main(){
    //	freopen("rally.in","r",stdin);
    //	freopen("rally.out","w",stdout);
    	n=read();m=read();k=read();
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j)
    			s[i][j]=read(),s[i][j]%=k;
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j)
    			s[i][j]=dec(add(s[i][j-1],add(s[i-1][j],s[i][j])),s[i-1][j-1]);
    	}
    	for(int i=0;i<=m;++i){
    		for(int j=i+1;j<=m;++j){
    			for(int ww=0;ww<=n;++ww){
    				int nw=dec(s[ww][j],s[ww][i]);
    				ans+=w[nw];
    				++w[nw];
    			}
    			for(int ww=0;ww<=n;++ww){
    				int nw=dec(s[ww][j],s[ww][i]);
    				--w[nw];
    			}
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    动画效果(二)
    动画效果(一)
    高级事件(二)
    高级事件(一)
    事件对象(二)
    事件对象(一)
    使用jquery ajax代替iframe
    SQL语句汇总(终篇)—— 表联接与联接查询
    SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
    SQL语句汇总(二)——数据修改、数据查询
  • 原文地址:https://www.cnblogs.com/tqxboomzero/p/13836939.html
Copyright © 2011-2022 走看看