数论(同余+hash)

Time Limit:3000MS Memory Limit:65536KB

Description You are given a sequence a[0]a[1] ... a[N-1] of digits and a prime number Q. For each i<=j with a[i] != 0, the subsequence a[i]a[i+1]...a[j] can be read as a decimal representation of a positive integer. Subsequences
with leading zeros are not considered. Your task is to count the number of pairs (i, j) such that the corresponding subsequence modulo Q is R. Input The input consists of at most 10 datasets. Each dataset is represented by a line containing four integers N,
S, W, Q, and R, separated by spaces, where 1<=N<=10^5, 1<=S<=10^9, 1<=W<=10^9, Q is a prime number less than 10^9 and 0<=R<Q. The sequence a[0]...a[N-1] of length N is generated by the following code.

int g = S;

for (int i=0; i<N; i++) {

a[i] = (g/7) % 10;

if( g%2 == 0 ) { g = (g/2); }

else { g = (g/2) ^ W; }

}

Note: the operators /, %, and ^ are the integer division, the modulo, and the bitwise exclusiveor, respectively. The above code is meant to be a random number generator. The intended solution does not rely on the way how the
sequence is generated. The end of the input is indicated by a line containing five zeros separated by spaces. Output For each dataset, output the answer in a line.

Sample Input

3 32 64 7 0

4 35 89 5 0

5 555 442 3 0

5 777 465 11 0

100000 666 701622763 65537

0 0 0 0 0 0

Sample Output

2

4

6

3

68530

Hint In the first dataset, the sequence is 421. We can find two multiples of Q = 7, namely, 42 and 21. In the second dataset, the sequence is 5052, from which we can find 5, 50, 505, and 5 being the multiples of Q = 5. Notice
that we don‘t count 0 or 05 since they are not a valid representation of positive integers. Also notice that we count 5 twice, because it occurs twice in different positions. In the third and fourth datasets, the sequences are 95073 and 12221, respectively.

题目大意

给出一串十进制的数字,求其中有多少个子串所表示的数字模质数p的值为r

思路

假设一个子串为x[i]x[i+1]...x[j],则模p的值为(x[i]*10^(j-i)+x[i+1]*10^(j-i-1)+...+x[j]*10^0)%p,如果用f[n]表示(10^n)%p, t[n]表示原串的后n位模p的值,那么x[i]x[i+1]...x[j] %p=r等价于t[i]=(t[j-1]+r*10^(j-1))%p=(t[j-1]+r*f[j-1])%p,((a/b)%c=(a%(b*c)),这样以第i位开头的数字中符合要求的个数即为符合该式的j的个数(j>=i)。可以用map或哈希记录个数,m[x]表示符合(t[j]+r*f[j])%p=x的j的个数。

做法

按题目给的方法生成数字串,预处理求出f[n],再从右向左依次处理出t[n],将答案加上m[t[n]],再更新m[(t[n]+r*f[n])%p]即可。

说明

当题目中的质数为2或5时需要特殊处理,因为10可以被2或5整除,不能再用10的幂次的形式取余。此时只需要从高位向地位,不断统计最后一位模p为r的子串个数即可,因为一个数除2或5的余数就等于最后一位模2或5.

数字的首位不能为0,所以要注意只有当前位不为0时才能更新答案。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=100005;
long long a[N];
long long f[N];
void init(int n,long long s,long long w)
{
	long long g=s;
	for (int i=1; i<=n; i++)
	{
		a[i]=(g/7)%10;
		if (g%2==0) g=g/2;
		else g=(g/2)^w;
	}
}
int main()
{
	int n,i;
	long long s,w,q,r;
	long long x,y,ans;
	while (scanf("%d%lld%lld%lld%lld",&n,&s,&w,&q,&r)==5)
	{
		if (n==0 && s==0 && w==0 && q==0 && r==0) break;
		init(n,s,w); ans=0;
		if (q==2 || q==5)
		{
			s=0;
			for (i=1; i<=n; i++){
				if (a[i]!=0) s++;
				if (a[i]%q==r) ans+=s;
			}
		}
		if (q!=2 && q!=5)
		{
			f[n]=1;
			for (i=n-1; i>=1; i--) f[i]=(f[i+1]*10)%q;
			map<int,int> m;
			m[r]=1;
			x=0;
			for (i=n; i>=1; i--)
			{
				x=(x+a[i]*f[i])%q;
				if (a[i]!=0)ans+=m[x];
				m[(r*f[i-1]+x)%q]++;
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
} 
时间: 2024-08-11 09:49:29

数论(同余+hash)的相关文章

数论 --- 同余定理

声明:以下文章是借鉴了别人的再加上自己补充后的,转载请注明! 一.同余 对于整数除以某个正整数的问题,如果只关心余数的情况,就产生同余的概念. 定义1 用给定的正整数m分别除整数a.b,如果所得的余数相等,则称a.b对模m同余,记作a≡b(mod m),如 56≡0 (mod 8). 举个例子: 3%2=1 5%2=1 则有: (5-3)%=0 [同余性质] 1) 自反性 2) 传递性 3) 对称性 4) 若 a ≡ b (mod m), c ≡ d (mod m) 则 a+b ≡ b+ d(m

hdu 1664(数论+同余搜索+记录路径)

Different Digits Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1430    Accepted Submission(s): 392 Problem Description Given a positive integer n, your task is to find a positive integer m, w

LightOJ1214 Large Division 基础数论+同余定理

Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if there exists an integer c such that a = b * c. Input Input starts with an integer T (≤ 525), denot

ZOJ 1136 Multiple(BFS + 数论 同余剪枝 搜索数字的倍数 )

ZOJ Problem Set - 1136 Multiple Time Limit: 10 Seconds Memory Limit: 32768 KB a program that, given a natural number N between 0 and 4999 (inclusively), and M distinct decimal digits X1,X2..XM (at least one), finds the smallest strictly positive mult

数论——同余

HDU 1212  题目链接  点击打开链接 description:给定一个大数a, 求模b的结果. 题目分析:由于a很大,因此需要引入字符串进行处理! 算法分析:   同余定理 1. ( m + n ) % c =  (m % c + n% c) % c 2. (m* n ) % c =( (m % c ) * ( n% c))  % c 3. (m ^ n) % c = ((m % c) ^ n)  % c                   (此定理可用于快速幂运算   另作讨论) 此题

一致性hash算法--负载均衡

有没有好奇过redis.memcache等是怎么实现集群负载均衡的呢? 其实他们都是通过一致性hash算法实现节点调度的. 讲一致性hash算法前,先简述一下求余hash算法: hash(object)%N 一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) : 由于QPS升高,我们需要添加多一台服务器,这时候服务器是 N+1 台,映射公式变成了 hash(obje

POJ3349 Snowflake Snow Snowflakes

Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 39075   Accepted: 10232 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read inf

_00013 一致性哈希算法 Consistent Hashing 探讨以及相应的新问题出现解决

一.业务场景 假如我们现在有12台Redis服务器(其它的什么东西也行),有很多User(用户)的数据数据从前端过来,然后往12台redis服务器上存储,在存储中就会出现一个问题,12台服务器,有可能其中几台Redis服务器上(简称集群A)存了很多的数据,然后另外几台Redis服务器(简称集群B)上存的数据很少,这样的话那 A 上的读写压力就会很大(当然,这个要看你的数据量的大小了,如果你数据量很小的话,基本无压力了,但是数据量很大,那就 ...),对于这样的问题,我们通常的解决办法是什么呢 ?

_00013 一致性哈希算法 Consistent Hashing 新的讨论,并出现相应的解决

笔者博文:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前.妳却感觉不到我的存在 技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术 转载声明:能够转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作. qq交流群:214293307  idkey=bf80524ac3630cb09