Be Efficient(Light Oj 1134)
阿新 • • 發佈:2018-10-02
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/6View Code3 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 }
Be Efficient(Light Oj 1134)