Luo Gu [P3281] [SCOI2013] count

Title Description

Fish is a live fish in the sea, one day he was bored and started to count to play. Specific rules he is playing count:

Determine the number of decimal number B

Determining a count of the interval [L, R]

For every number between the [L, R], to the number as a character string, a list each (consecutive) hex value of the B sub-string corresponding to the string.

Sum of all the listed number. Fish now count the number again, but not sure of the results are correct. Since [L, R] is large, he did not have the extra energy to verify correct, you can write a program to help him verify it?

Input Format

Input contains three lines.

The first row is only a few B, represented by hexadecimal number.

The second row has a number N + 1, the first number is N, L represents a length in the B band is N, the number N Took over from high to low number indicates each particular one of L .

The third row has the number M + 1, M is the first number, length represents the number of R in B is M-ary, per a specific number of M Took over from high to low R represents the number.

Output Format

Output only one row, i.e., the number of rules in accordance with the results of Fish number, hexadecimal 10 with the results, since this number can be large, the output of the digital to analog modulus of 20,130,427.

Sample input and output

Copy Input # 1
10
. 3. 3 1 0
. 3 0 1. 3
output copy # 1
120

Description / Tips

Sample [explain]

[103, 103] 103 among only a few, the number of all sub-strings comprising 1, 10, 103, 0, 03, 3, and 120.

[Agreed] with the data range

20% of the data, 0 <= R <= L <= 10 ^ 5.

50% 数据,2 <= B <= 1000,1 <= N,M <= 1000。

100% 数据,2 <= B <= 10^5,1 <= N,M <= 10^5。

Thinking

First, we consider solving such a problem, seek [, x-1) in the answer to all numbers 1

The x written in hexadecimal form B x1, x2, x3, ..., xn.

First, consider the number of bits less than n

Then for reaching the number n bit, the first digit enumerator less than xi.

Because it is an open interval, there must be such a digit.

This method can reduce the classification leading zeros, it is quite easy

Here to talk about this question of DP

This question is the integration of a very strong mathematical thought

Hereinafter set P [i] = 10 ^ i, S [i] to P [i] and the prefix

Consider a given number x1, x2, ..., xn, and find its substring.

Consider the contribution of each digit, the contribution of the i-th digit is

i * xi * S [n - i]
is understood about this formula

Definition of d [i] [0] represents a bit i have to fill out, and all the prefix substring, d [i] [1] represents a bit i have to fill out, and all sub-strings.

The transfer is quite evident

For less than the number of n bits, apparently direct enumeration highest on the list

After the first one less than the number of bits xi, xi before the first digit is less than, less than the first digit xi: Up to n-bit number, we need to consider the contribution of three sections, namely,

Specific circumstances can look at the code below

However, we still have not solved a problem

The above approach is O (nB) of.

As long as this bit enumeration filled by what changed

1 + 2 + ... + n = n * (n + 1) / 1
Optimization Click to

SV code represents the contribution period of the original prefix number x on the whole number

You should be careful before each DP cleared SV.

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 20130427;
int cnt, a[100005];
int B, SV[100005], d[100005][2], P[100005], S[100005];
void read()
{
	memset(SV, 0, sizeof(SV));
	for(int i = cnt - 1; i >= 0; i--)
		scanf("%lld", &a[i]), SV[i] = (SV[i + 1] + a[i] * (cnt - i) % mod * S[i] % mod) % mod;
}
int calc(int x, bool p)
{
	if(x <= 0) return 0;
	if(d[x][p] != -1) return d[x][p];
	if(p)
		return d[x][1] = (B * calc(x - 1, 1) % mod + (B * (B - 1) / 2) % mod * P[x - 1] % mod * S[x - 1] % mod + B * calc(x - 1, 0) % mod) % mod;
	else
		return d[x][0] = (B * calc(x - 1, 0) % mod + (B * (B - 1) / 2) % mod * P[x - 1] % mod * S[x - 1] % mod) % mod;
}
int solve()
{
	int i, ans = 0;
	for(i = 1; i < cnt; i++)
		ans = (ans + (B - 1) * calc(i - 1, 1) % mod + (B * (B - 1) / 2) % mod * P[i - 1] % mod * S[i - 1] % mod + (B - 1) * calc(i - 1, 0) % mod) % mod;
	for(i = cnt - 1; i >= 0; i--)
		if(i == cnt - 1)
			ans = (ans + (a[i] * (a[i] - 1) / 2) % mod * P[i] % mod * S[i] % mod + (a[i] - 1) * calc(i, 1) % mod + (a[i] - 1) * calc(i, 0) % mod) % mod;
		else
			ans = (ans + SV[i + 1] * a[i] % mod * P[i] % mod + (a[i] * (a[i] - 1) / 2) % mod * P[i] % mod * S[i] % mod * (cnt - i) % mod + a[i] * calc(i, 1) % mod + a[i] * calc(i, 0) % mod * (cnt - i) % mod) % mod;
	return ans;
}
int count()
{
	return SV[0];
}
signed main()
{
	int a1, a2, c1, c2;
	memset(d, -1, sizeof(d));
	scanf("%lld%lld", &B, &cnt);
	P[0] = S[0] = 1;
	for(int i = 1; i <= 100003; i++)
		P[i] = P[i - 1] * B % mod, S[i] = (S[i - 1] + P[i]) % mod;
	read();
	c1 = count();
	a1 = solve();
	scanf("%lld", &cnt);
	read();
	c2 = count();
	a2 = solve();
	printf("%lld\n", (a2 - a1 + c2 + mod * mod) % mod);
	return 0;
}
Published 703 original articles · won praise 392 · Views 140,000 +

Guess you like

Origin blog.csdn.net/Eric1561759334/article/details/100576465