1. 程式人生 > >Be Efficient(Light Oj 1134)

Be Efficient(Light Oj 1134)

none printf ++ 尺寸 image 兩個 mark pre set

題目傳送門:Be Efficient

題意:輸入n和m,然後輸入有n個元素的一個序列,問有多少個子序列元素的和能整除m。

思路:求前綴和,利用一個前綴的一個定理求解。

前綴和的一個定理是:每次求的前綴和對m取余,兩個相等的結果之間的序列的和就是m的倍數。

技術分享圖片技術分享圖片?

如上序號1、4的結果相同,則序號2、3、4的和是4的倍數,序號2、3的結果相同,則序號3是4的倍數。

註意:將儲存取余結果的數組pre的pre[0]設置為1,因為後邊前綴和取余為0,表明這一組自己就是4的倍數,直接從1開始。

PS:用long long,算錯了數據範圍,被爆int卡到吐……

代碼:

技術分享圖片
 1 /*
 2     Time:2018/9/6
3 Writer:Sykai 4 Function:L 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <algorithm> 9 #include <set> 10 #include <cstring> 11 #include <queue> 12 #define INF 0x3f3f3f3f 13 #define FRE() freopen("in.txt","r",stdin) 14 using namespace std;
15 const int maxn = 1e5+10; 16 const int MOD = 1e9 + 7; 17 typedef long long ll; 18 typedef pair<int,int> P; 19 ll pre[maxn],n,m; 20 21 inline void init() 22 { 23 memset(pre,0,sizeof(pre)); 24 } 25 26 int main() 27 { 28 int T,cnt = 0; 29 scanf("%d",&T); 30 while(T--) 31 {
32 scanf("%lld%lld",&n,&m); 33 init(); 34 ll sum = 0,ans = 0; 35 pre[0] = 1; 36 for(int i = 1; i<=n; i++) 37 { 38 ll t; 39 scanf("%lld",&t); 40 sum = (sum+t) % m; 41 ans += pre[sum]; 42 pre[sum]++; 43 } 44 printf("Case %d: %lld\n",++cnt,ans); 45 } 46 return 0; 47 }
View Code

Be Efficient(Light Oj 1134)