給你乙個的$n*m$矩陣,每個格仔裡都有乙個不超過$k$的正整數。詢問這個矩陣裡有多少個不同的子矩形中的數字之和是$k$的倍數?
我們先考慮乙個簡化版的一維問題:給定乙個長度為$n$的序列,$a[1],a[2],\cdots,a[n]$,如果某一段子串行的和為$k$的倍數,則稱其為$k$倍區間,求該序列中有多少個$k$倍區間,要求時間複雜度為$o(n)$。
設$sum$為該序列的字首和,那麼若$(sum[r]-sum[l-1])%k==0$,則區間$[l,r]$符合條件,但暴力列舉複雜度為$o(n^2)$,不符合條件。
考慮優化,將上式變形後為$sum[l-1]%k==sum[r]%k$,所以我們可以用桶來處理在$i$之前字首和為$sum[i]$的數量。
繼續考慮原問題,我們可以列舉兩行,再列舉列,把這一列合為乙個數,即可用上述方法解決。
#include#include#include#include#includeusing namespace std;#define r register
#define ll long long
inline ll read()
while(cc>='0'&&cc<='9')
return aa*bb;
}const int n=403;
const int m=1e6+3;
int n,m,mod,sum[n][n],a[n];
ll ans,cnt[m];
int main()
} for(r int i=1;i<=n;++i)
ans+=cnt[0];
//可理解為加上本來就為k的倍數的區間個數,可寫成上述注釋。
for(r int k=1;k<=m;++k)cnt[a[k]]=0;
} }printf("%lld\n",ans);
return 0;
}
洛谷3941 入陣曲
標籤 模擬,字首和 題目描述 小 f 很喜歡數學,但是到了高中以後數學總是考不好。有一天,他在數學課上發起了呆 他想起了過去的一年。一年前,當他初識演算法競賽的 時候,覺得整個世界都煥然一新。這世界上怎麼會有這麼多奇妙的東西?曾經自己覺得難以解決的問題,被乙個又乙個演算法輕鬆解決。小 f 當時暗自覺...
洛谷P2119 魔法陣
六十年一次的魔法戰爭就要開始了,大魔法師準備從附近的魔法場中汲取魔法能量。大魔法師有m個魔法物品,編號分別為1,2,m。每個物品具有乙個魔法值,我們用xi表示編號為i的物品的魔法值。每個魔法值xi是不超過n的正整數,可能有多個物品的魔法值相同。大魔法師認為,當且僅當四個編號為a,b,c,d的魔法物品...
洛谷P2119 魔法陣
六十年一次的魔法戰爭就要開始了,大魔法師準備從附近的魔法場中汲取魔法能量。大魔法師有m個魔法物品,編號分別為1,2,m。每個物品具有乙個魔法值,我們用xi表示編號為i的物品的魔法值。每個魔法值xi是不超過n的正整數,可能有多個物品的魔法值相同。大魔法師認為,當且僅當四個編號為a,b,c,d的魔法物品...