入陣曲 (組合數 餘數統計)

入陣曲

10.24

思路:
明顯的n3複雜度,考慮n2卡住上下界,組合數計數優化,由於模數比較小,我們維護了每一列的前綴之後,就可以O(1)計算固定上下界的前綴矩形的值了。記錄每個前綴矩形modK的餘數,記錄每種餘數有多少個,同種餘數的前綴矩形相減就是合法。清空不要用memset會T。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#define LL long long
#define N 410
using namespace std;

int n, m, k, idc=0;
int mp[N][N], res[N];
int cnt[1000010];
LL sum[N][N];
LL ans=0;

inline int read(){
    int 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;
}

int main() {
    freopen ("rally.in", "r", stdin);
    freopen ("rally.out", "w", stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(register int i=1; i<=n; i++){
        for(register int j=1; j<=m; j++){
            mp[i][j] = read();
            sum[i][j] = sum[i-1][j] + mp[i][j];
        }
    }
    for(register int i=0; i<n; i++){
        for(register int j=i+1; j<=n; j++){
            LL cc = 0;
            for(register int p=1; p<=m; p++){
                cc = ( (cc + sum[j][p] - sum[i][p]) % k + k ) % k;
                cnt[cc]++; res[++idc] = cc;
            }
            cnt[0]++;
            for(register int x=1; x<=idc; x++){
                int d = res[x];
                ans += cnt[d] * (cnt[d] - 1) / 2;
                cnt[d] = 0;
            }
            cnt[0] = 0;
            idc = 0;
        }
    }
    cout << ans << endl;
    return 0;
}
發佈了308 篇原創文章 · 獲贊 25 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章