ACM选修HUST1058(市赛题) Lucky Sequence 同余定理

Description

Edward  得到了一个长度为  N  的整数序列,他想找出这里面有多少个“幸运的”
连续子序列。一个连续子序列被称为“幸运的”,当且仅当该子序列内的整数之
和恰好是  K  的整数倍数。他请求你写一个程序来计算他喜欢的连续子序列个数.

Input

输入第一行是一个整数  T,表示有  T  组数据。
每组数据第一行是两个整数  N (1 <= N <= 10^6), K (1 <= K <= 10^9)。
接下来的一行包含  N  个整数  Ai (|Ai| <= 10^9)。

Output

对于每组测试数据,输出一行仅包含一个整数,表示  Edward  喜欢的连续子序
列数量。

Sample Input

2
5 3
1 2 3 4 1
6 2
1 2 1 2 1 2

Sample Output

4
9

HINT

一开始没有想到同余定理,根据nanako大神的说法,可以差不多刚好卡时间和内存AC,但是鶸并不会..

记得当时模拟赛后,nanako对这题的脑洞已经几乎完全接近正解了。

分析:根据同余定理:(a-b)%c=a%c-b%c,可以想到使用前缀和,并记录每个前缀和的模k后的值,O(n^2)的解法是两层循环 前缀数组模k套公式,显然超时(好蠢,再找到有几个相同余数的数。例如样例二:前缀和并模K后的数组为1 1 0 0 1 1 ,找到余数相同的 b[0],b[1],b[4],b[5],4个,那么在其中取首尾,不同位置的组合有 (3+1)*(3)/2=6,同样的,零有2个,但要注意余数为0的话意味着该位置的前缀和本身就是K的倍数,所以0的组合为 (2+1)*2/2=3。

注意点:给出的数有可能是负数,故求余数时需要变换。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define ll long long
 6 using namespace std;
 7
 8 int a[1000010], b[1000010];
 9 int Xe(int a)
10 {
11     return (a+1)*(a)/2;
12 }
13 int main()
14 {
15     int T, t;
16     int n, k;
17     ll  x, ans;
18     scanf("%d", &T);
19         while(T--)
20         {
21             scanf("%d%d", &n, &k);
22
23             ans=0;
24             scanf("%d",&b[0]);
25             b[0]%=k;
26             if(b[0] < 0)          //注意负数变换
27                 b[0]=(b[0]+k)%k;
28
29
30             for(int i=1; i<n; i++)
31             {
32                 scanf("%d",&a[i]);
33                 b[i]=b[i-1]+a[i];
34                 b[i]%=k;
35                 if(b[i]<0)       //注意负数变换
36                     b[i]=(b[i]+k)%k;
37             }
38             sort(b, b+n);     //排序后方便处理
39             b[n]=-1;
40             /*for(int i=1; i<=n; i++)
41             {
42                 cout<<b[i]<" ";
43             }
44
45             for(int i = 1; i <= n; i++)         //O(n^2)明显T呀大哥
46             {
47                 for(int j = 0; j < i; j++)
48                 {
49                     if(!((k+b[i]%k-b[j]%k)%k))
50                     {
51                         ans++;
52                         //printf("%d~%d\n",i,j );
53                     }
54                 }
55             }*/
56             x=1;
57             for(int i = 1; i <= n; i++)
58        {
59                 if(b[i]==b[i-1])
60                     x++;
61                 else
62          {
63                     if(b[i-1]!=0)       //非0的情况
64                         x--;
65                     ans+=Xe(x);
66                     x=1;
67          }
68        }
69             printf("%lld\n", ans);
70       }
71 }
时间: 2024-08-06 16:02:22

ACM选修HUST1058(市赛题) Lucky Sequence 同余定理的相关文章

2016湖南省赛----A 2016 (同余定理)

2016湖南省赛----A 2016 (同余定理) Description 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) 的数量: 1. 1≤a≤n,1≤b≤m; 2. a×b 是 2016 的倍数. Input 输入包含不超过 30 组数据. 每组数据包含两个整数 n,m (1≤n,m≤10 9). Output 对于每组数据,输出一个整数表示满足条件的数量. Sample Input 32 63 2016 2016 1000000000 1000000000 Sample

CSDN 厦门大学线下编程比赛第一题:求和(同余定理)

题目意思: 给定a和n,计算a+aa+aaa+aaaa+...+a...a(n个a) 的和. 输入描述:测试数据有多组,以文件结尾.每行输入a,n(1<=a,n<=1000000).输出描述:由于结果可能比较大,所以请输出答案mod 1000000007. http://student.csdn.net/mcs/programming_challenges 题目分析: 同余定理: s=0; abc&MOD=((a*10%MOD+b%MOD)*10%MOD+a%MOD)%MOD: //迭

2013 ACM/ICPC 长沙现场赛 A题 - Alice&#39;s Print Service (ZOJ 3726)

Alice's Print Service Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is providing print service, while the pricing doesn't seem to be reasonable, so people using her print service found some tricks to save money. For example, the price when

Sdut 2165 Crack Mathmen(数论)(山东省ACM第二届省赛E 题)

Crack Mathmen TimeLimit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 Since mathmen take security very seriously, theycommunicate in encrypted messages. They cipher their texts in this way: for everycharacther c in the message, they replace c wit

hdu 4089 不错的DP 北京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4089 还有疑惑,需要重新推: 但是学到的: 1.A=a+b+c  abc是三种情况,那么P(A)=a*P(a->事件)+b*P(b->事件)+c*P(c->事件); a->事件意思是 在a情况下的事件,就是全概率公式的思想吧 2.一定注意每一步会不会出现分母为0 的情况,以及预处理的时候对于一些特殊情况导致自己的式子会出现分母为0的排除掉 3.概率DP经常出现推出了式子但是自己不会写代码的情况,

山东省赛题 NEU OJ 1444 线段树双标记

http://acm.neu.edu.cn/hustoj/problem.php?id=1444 OJ问题论坛发帖http://t.cn/zjBp4jd FAQ http://t.cn/zjHKbmN Linux问题看http://t.cn/aWnP1n 1444: Devour Magic 时间限制: 1 Sec  内存限制: 256 MB 提交: 129  解决: 21 [提交][状态][讨论版] 题目描述 In Warcraft III, Destroyer is a large flyi

O准备如何苟进复赛圈?华为软挑开挂指南(附赛题预测)

事先声明,这不是华为软挑的软广,我也不是海军. 这篇文章纯粹是心血来潮,原因是去年上传到github的参赛代码,前几天又有两个人star和fork了. 记得star热潮还是去年4月复赛刚结束的那几天,厚着脸皮在八大赛区的群里发消息求关注,之后就陷入了无限吃灰期.结果,我的开源代码在前几天突然又被挖出来了. 看了下时间,我想大概是有同学在准备今年的比赛,尝试研究去年的题目和开源代码.说实话,即使你愿意花很长时间来准备,效果也有限. 因为看往年的题目很容易陷进去,等到真正比赛发现意义不大.另外,很少

CSU OJ 1112机器人的指令 (湖南省12年省赛题)

 Welcome to CSU Online Judge! 1112: 机器人的指令 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 274  Solved: 97 [Submit][Status][Web Board] Description 数轴原点有一个机器人.该机器人将执行一系列指令,你的任务是预测所有指令执行完毕之后它的位置. ·LEFT:往左移动一个单位 ·RIGHT: 往右移动一个单位 ·SAME AS i: 和第i 条执行相同的

CSDN 轻松周赛赛题:能否被8整除

轻松周赛赛题:能否被8整除 题目详情 给定一个非负整数,问能否重排它的全部数字,使得重排后的数能被8整除. 输入格式: 多组数据,每组数据是一个非负整数.非负整数的位数不超过10000位. 输出格式 每组数据输出一行,YES或者NO,表示能否重排它的全部数字得到能被8整除的数.注意: 重排可以让0开头. 答题说明 输入样例   610 122 输出样例   YES NO 解释   第一个数可以变为016 , 160 解题:很水的一道题...思路很简单,1000是能被8整除的,所以一千的倍数都能被