AtCoder Beginner Contest 300——A-G题讲解

蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!

Hello, 大家好哇!本初中生蒟蒻讲解一下AtCoder Beginner Contest 300这场比赛的A-G题

===========================================================================================

A - N-choice question

原题

Problem Statement

Given integers A A A and B B B, find A + B A+B A+B.

This is a N N N-choice problem; the i i i-th choice is C i C_i Ci.

Print the index of the correct choice.

Constraints

All values in the input are integers.
1 ≤ N ≤ 300 1 \le N \le 300 1N300
1 ≤ A , B ≤ 1000 1 \le A,B \le 1000 1A,B1000
1 ≤ C i ≤ 2000 1 \le C_i \le 2000 1Ci2000
C i C_i Ci are pairwise distinct. In other words, no two choices have the same value.
There is exactly one i i i such that A + B = C i A+B=C_i A+B=Ci. In other words, there is always a unique correct choice.

Input

The input is given from Standard Input in the following format:

N N N A A A B B B
C 1 C_1 C1 C 2 C_2 C2 … \dots C N C_N CN

Output

Print the answer as an integer.

Sample Input 1

3 125 175
200 300 400

Sample Output 1

2

We have 125 + 175 = 300 125+175 = 300 125+175=300.

The first, second, and third choices are 200 200 200, 300 300 300, and 400 400 400, respectively.

Thus, the 2 2 2-nd choice is correct, so 2 2 2 should be printed.

Sample Input 2

1 1 1
2

Sample Output 2

1

The problem may be a one-choice problem.

Sample Input 3

5 123 456
135 246 357 468 579

Sample Output 3

5

题目大意

就是找出C序列中第几个数是A+B的和。


思路

太简单,不写了,直接见代码

代码

#include 

using namespace std;

int main()
{
	int n, a, b;
	
	cin >> n >> a >> b;
	
	int c = a + b, t;
	for (int i = 1; i<= n; i ++)
	{
		cin >> t;
		if (t == c)
		{
			cout << i << endl;
			return 0;
		}
	}
}

B - Same Map in the RPG World

原题

Problem Statement

Takahashi is developing an RPG. He has decided to write a code that checks whether two maps are equal.

We have grids A A A and B B B with H H H horizontal rows and W W W vertical columns. Each cell in the grid has a symbol # or . written on it.

The symbols written on the cell at the i i i-th row from the top and j j j-th column from the left in A A A and B B B are denoted by A i , j A_{i, j} Ai,j and B i , j B_{i, j} Bi,j, respectively.
The following two operations are called a vertical shift and horizontal shift.
For each j = 1 , 2 , … , W j=1, 2, \dots, W j=1,2,,W, simultaneously do the following:
simultaneously replace A 1 , j , A 2 , j , … , A H − 1 , j , A H , j A_{1,j}, A_{2,j}, \dots, A_{H-1, j}, A_{H,j} A1,j,A2,j,,AH1,j,AH,j with A 2 , j , A 3 , j , … , A H , j , A 1 , j A_{2,j}, A_{3,j}, \dots, A_{H,j}, A_{1,j} A2,j,A3,j,,AH,j,A1,j.
For each i = 1 , 2 , … , H i = 1, 2, \dots, H i=1,2,,H, simultaneously do the following:
simultaneously replace A i , 1 , A i , 2 , … , A i , W − 1 , A i , W A_{i,1}, A_{i,2}, \dots, A_{i,W-1}, A_{i,W} Ai,1,Ai,2,,Ai,W1,Ai,W with A i , 2 , A i , 3 , … , A i , W , A i , 1 A_{i, 2}, A_{i, 3}, \dots, A_{i,W}, A_{i,1} Ai,2,Ai,3,,Ai,W,Ai,1.
Is there a pair of non-negative integers ( s , t ) (s, t) (s,t) that satisfies the following condition? Print Yes if there is, and No otherwise.
After applying a vertical shift s s s times and a horizontal shift t t t times, A A A is equal to B B B.
Here, A A A is said to be equal to B B B if and only if A i , j = B i , j A_{i, j} = B_{i, j} Ai,j=Bi,j for all integer pairs ( i , j ) (i, j) (i,j) such that 1 ≤ i ≤ H 1 \leq i \leq H 1iH and 1 ≤ j ≤ W 1 \leq j \leq W 1jW.

Constraints

2 ≤ H , W ≤ 30 2 \leq H, W \leq 30 2H,W30
A i , j A_{i,j} Ai,j is # or ., and so is B i , j B_{i,j} Bi,j.
H H H and W W W are integers.

Input

The input is given from Standard Input in the following format:

H H H W W W
A 1 , 1 A 1 , 2 … A 1 , W A_{1,1}A_{1,2}\dots A_{1,W} A1,1A1,2A1,W
A 2 , 1 A 2 , 2 … A 2 , W A_{2,1}A_{2,2}\dots A_{2,W} A2,1A2,2A2,W
⋮ \vdots
A H , 1 A H , 2 … A H , W A_{H,1}A_{H,2}\dots A_{H,W} AH,1AH,2AH,W
B 1 , 1 B 1 , 2 … B 1 , W B_{1,1}B_{1,2}\dots B_{1,W} B1,1B1,2B1,W
B 2 , 1 B 2 , 2 … B 2 , W B_{2,1}B_{2,2}\dots B_{2,W} B2,1B2,2B2,W
⋮ \vdots
B H , 1 B H , 2 … B H , W B_{H,1}B_{H,2}\dots B_{H,W} BH,1BH,2BH,W

Output

Print Yes if there is a conforming integer pair ( s , t ) (s, t) (s,t); print No otherwise.

Sample Input 1

4 3
..#
...
.#.
...
#..
...
.#.
...

Sample Output 1

Yes

By choosing ( s , t ) = ( 2 , 1 ) (s, t) = (2, 1) (s,t)=(2,1), the resulting A A A is equal to B B B.

We describe the procedure when ( s , t ) = ( 2 , 1 ) (s, t) = (2, 1) (s,t)=(2,1) is chosen. Initially, A A A is as follows.

..#
...
.#.
...

We first apply a vertical shift to make A A A as follows.

...
.#.
...
..#

Then we apply another vertical shift to make A A A as follows.

.#.
...
..#
...

Finally, we apply a horizontal shift to make A A A as follows, which equals B B B.

#..
...
.#.
...

Sample Input 2

3 2
##
##
#.
..
#.
#.

Sample Output 2

No

No choice of ( s , t ) (s, t) (s,t) makes A A A equal B B B.

Sample Input 3

4 5
#####
.#...
.##..
..##.
...##
#...#
#####
...#.

Sample Output 3

Yes

Sample Input 4

10 30
..........##########..........
..........####....###.....##..
.....##....##......##...#####.
....####...##..#####...##...##
...##..##..##......##..##....#
#.##....##....##...##..##.....
..##....##.##..#####...##...##
..###..###..............##.##.
.#..####..#..............###..
#..........##.................
................#..........##.
######....................####
....###.....##............####
.....##...#####......##....##.
.#####...##...##....####...##.
.....##..##....#...##..##..##.
##...##..##.....#.##....##....
.#####...##...##..##....##.##.
..........##.##...###..###....
...........###...#..####..#...

Sample Output 4

Yes

题目大意

两个仅由#. 组成的矩阵A和B,A的各行可以同时向右转动,最后边的列到最左边,各列可以同时向上转动,最上面的到最下面,问这种变动能否使得A和B相等。


思路

通过遍历和模拟就可以完成,比较简单,直接见代码。


代码

#include
using namespace std;
const int N = 35;

string a[N], b[N], mycp[N], mydp[N];
bool flag;
int nop;

int main(){
    int h,w;
    cin >> h >> w;
    for(int i =1 ;i <= h; i ++) cin >> a[i];
    
    for(int i =1 ;i <= h; i ++) cin >> b[i];
    
    for(int i =1 ;i <= h; i ++) mycp[i] = a[i] + a[i];
   
    
    for(int i = 1; i <= h ;i ++){
     
        for(int j = 0; j <= w*2 -1 ;j ++){
            
            for(int x = 1; x <= h; x++){
        
                if(mycp[i].substr(j,w) ==  b[x]){
                    nop = 1;
                    for(int t = i; t <= h; t++) mydp[nop ++] = mycp[t].substr(j,w);
                        
                    for(int t = 1 ; t < i ; t++) mydp[nop ++] = mycp[t].substr(j,w);
                    
                    flag = 0;
                    for(int t = 1; t <= nop ; t ++) if(mydp[t] != b[t]) flag = 1;
                    
                    if(flag == 0){
                        cout <<"Yes"<<endl;
                        return 0;
                    } 
                }
            }
        }
    }
    cout << "No" <<endl;
    return 0;
}

C - Cross

原题

Problem Statement

We have a grid with H H H horizontal rows and W W W vertical columns. We denote by ( i , j ) (i, j) (i,j) the cell at the i i i-th row from the top and j j j-th column from the left of the grid.

Each cell in the grid has a symbol # or . written on it. Let C [ i ] [ j ] C[i][j] C[i][j] be the character written on ( i , j ) (i, j) (i,j). For integers i i i and j j j such that at least one of 1 ≤ i ≤ H 1 \leq i \leq H 1iH and 1 ≤ j ≤ W 1 \leq j \leq W 1jW is violated, we define C [ i ] [ j ] C[i][j] C[i][j] to be ..
( 4 n + 1 ) (4n+1) (4n+1) squares, consisting of ( a , b ) (a, b) (a,b) and ( a + d , b + d ) , ( a + d , b − d ) , ( a − d , b + d ) , ( a − d , b − d ) (a+d,b+d),(a+d,b-d),(a-d,b+d),(a-d,b-d) (a+d,b+d),(a+d,bd),(ad,b+d),(ad,bd) ( 1 ≤ d ≤ n , 1 ≤ n ) (1 \leq d \leq n, 1 \leq n) (1dn,1n), are said to be a cross of size n n n centered at ( a , b ) (a,b) (a,b) if and only if all of the following conditions are satisfied:
C [ a ] [ b ] C[a][b] C[a][b] is #.
C [ a + d ] [ b + d ] , C [ a + d ] [ b − d ] , C [ a − d ] [ b + d ] C[a+d][b+d],C[a+d][b-d],C[a-d][b+d] C[a+d][b+d],C[a+d][bd],C[ad][b+d], and C [ a − d ] [ b − d ] C[a-d][b-d] C[ad][bd] are all #, for all integers d d d such that 1 ≤ d ≤ n 1 \leq d \leq n 1dn,
At least one of C [ a + n + 1 ] [ b + n + 1 ] , C [ a + n + 1 ] [ b − n − 1 ] , C [ a − n − 1 ] [ b + n + 1 ] C[a+n+1][b+n+1],C[a+n+1][b-n-1],C[a-n-1][b+n+1] C[a+n+1][b+n+1],C[a+n+1][bn1],C[an1][b+n+1], and C [ a − n − 1 ] [ b − n − 1 ] C[a-n-1][b-n-1] C[an1][bn1] is ..
For example, the grid in the following figure has a cross of size 1 1 1 centered at ( 2 , 2 ) (2, 2) (2,2) and another of size 2 2 2 centered at ( 3 , 7 ) (3, 7) (3,7).
AtCoder Beginner Contest 300——A-G题讲解_第1张图片
The grid has some crosses. No # is written on the cells except for those comprising a cross.

Additionally, no two squares that comprise two different crosses share a corner. The two grids in the following figure are the examples of grids where two squares that comprise different crosses share a corner; such grids are not given as an input. For example, the left grid is invalid because ( 3 , 3 ) (3, 3) (3,3) and ( 4 , 4 ) (4, 4) (4,4) share a corner.
AtCoder Beginner Contest 300——A-G题讲解_第2张图片
Let N = min ⁡ ( H , W ) N = \min(H, W) N=min(H,W), and S n S_n Sn be the number of crosses of size n n n. Find S 1 , S 2 , … , S N S_1, S_2, \dots, S_N S1,S2,,SN.

Constraints

3 ≤ H , W ≤ 100 3 \leq H, W \leq 100 3H,W100
C [ i ] [ j ] C[i][j] C[i][j] is # or ..
No two different squares that comprise two different crosses share a corner.
H H H and W W W are integers.

Input

The input is given from Standard Input in the following format:

$H$ $W$
$C[1][1]C[1][2]\dots C[1][W]$
$C[2][1]C[2][2]\dots C[2][W]$
$\vdots$
$C[H][1]C[H][2]\dots C[H][W]$

Output

Print S 1 , S 2 , … S_1, S_2, \dots S1,S2,, and S N S_N SN, separated by spaces.

Sample Input 1

5 9
#.#.#...#
.#...#.#.
#.#...#..
.....#.#.
....#...#

Sample Output 1

1 1 0 0 0

As described in the Problem Statement, there are a cross of size 1 1 1 centered at ( 2 , 2 ) (2, 2) (2,2) and another of size 2 2 2 centered at ( 3 , 7 ) (3, 7) (3,7).

Sample Input 2

3 3
...
...
...

Sample Output 2

0 0 0

There may be no cross.

Sample Input 3

3 16
#.#.....#.#..#.#
.#.......#....#.
#.#.....#.#..#.#

Sample Output 3

3 0 0

Sample Input 4

15 20
#.#..#.............#
.#....#....#.#....#.
#.#....#....#....#..
........#..#.#..#...
#.....#..#.....#....
.#...#....#...#..#.#
..#.#......#.#....#.
...#........#....#.#
..#.#......#.#......
.#...#....#...#.....
#.....#..#.....#....
........#.......#...
#.#....#....#.#..#..
.#....#......#....#.
#.#..#......#.#....#

Sample Output 4

5 0 1 0 0 0 1 0 0 0 0 0 0 0 0

题目大意

从给点的矩阵中找由 #组成的图形,其中从中心 #往外一共有几层,按层数进行统计,分别输出1层、2层、3层……n层的个数。


思路

这道题我们可以枚举每一个#,对于每一个#,可以进行X型扩展,扩展的时候注意处理边界!(详情见代码吧!)


代码

#include 

using namespace std;

const int N = 1e2 + 10;

int h, w;
char c[N][N];
int s[N];

int main()
{
	cin >> h >> w;
	
	for (int i = 1; i <= h; i ++)
		for (int j = 1; j <= w; j ++)
			cin >> c[i][j];
			
	for (int i = 2; i < h; i ++)
		for (int j = 2; j < w; j ++)
			if (c[i][j] == '#')
			{
				int deep = 0;
				while (i + deep + 1 <= h && i - deep + 1 >= 1 && j - deep + 1 >= 1 && j + deep + 1 <= w && c[i + deep + 1][j - deep - 1] == '#' && c[i + deep + 1][j + deep + 1] == '#' && c[i - deep - 1][j - deep - 1] == '#' && c[i - deep - 1][j + deep + 1] == '#')
					deep ++;
				s[deep] ++;
			}
	
	for (int i = 1; i <= min(h, w); i ++)
		cout << s[i] << " ";
		
	return 0;
}

D - AABCC

原题

Problem Statement

How many positive integers no greater than N N N can be represented as a 2 × b × c 2 a^2 \times b \times c^2 a2×b×c2 with three primes a , b a,b a,b, and c c c such that a < b < c ?

Constraints

N N N is an integer satisfying 300 ≤ N ≤ 1 0 12 300 \le N \le 10^{12} 300N1012.

Input

The input is given from Standard Input in the following format:

N N N

Output

Print the answer as an integer.

Sample Input 1

1000

Sample Output 1

3

The conforming integers no greater than 1000 1000 1000 are the following three.
300 = 2 2 × 3 × 5 2 300 = 2^2 \times 3 \times 5^2 300=22×3×52
588 = 2 2 × 3 × 7 2 588 = 2^2 \times 3 \times 7^2 588=22×3×72
980 = 2 2 × 5 × 7 2 980 = 2^2 \times 5 \times 7^2 980=22×5×72

Sample Input 2

1000000000000

Sample Output 2

2817785

题目大意

对于质数 a , b a,b a,b, and c c c, a < b < c,问 a 2 × b × c 2 a^2 \times b \times c^2 a2×b×c2组成的小于N的数的个数。


思路

方法一:
由于 a 2 × b × c 2 ≤ N a^2 \times b \times c^2 \le N a2×b×c2N,且a < b < c,
所以 a 5 ≤ N a^5 \le N a5N a ≤ 400 a \le 400 a400
对于b和c只需要遍历到 1 0 6 10^{6} 106就足够了。
所以先把 1 0 6 10^{6} 106的所有质数求出来,a只取前78个,其它的直接遍历计算就可以了。
方法二:
基本于方法一的思路 一样,只是对于C可以采用二分进行快速计算。

代码

方法一:

#include 
#include 
#include 
#define int long long 

using namespace std;

const int  N = 1e6 + 10;

int n;
vector<int> prime;
bool st[N];

void div(int x)
{
    for (int i = 2; i <= x; i ++)
    {
        if (!st[i]) prime.push_back(i);
        for (int j = 0; prime[j] <= x / i; j ++)
        {
            st[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

signed main()
{
	cin >> n;
	
	div(1000000);
	
	int res = 0;
	for (int i = 0; i < 78; i ++)
		for (int j = i + 1; prime[i] * prime[j] * prime[j] * prime[i] * prime[j] <= n; j ++)
			for (int k = j + 1; prime[i] * prime[j] * prime[k] * prime[i] * prime[k] <= n; k ++)
				res ++;
					
	cout << res << endl;
	return 0;
}

方法二:

#include 
#include 
#include 
#define int long long 

using namespace std;

const int  N = 1e6 + 10;

int n;
vector<int> prime;
bool st[N];

void div(int x)
{
    for (int i = 2; i <= x; i ++)
    {
        if (!st[i]) prime.push_back(i);
        for (int j = 0; prime[j] <= x / i; j ++)
        {
            st[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

signed main()
{
	cin >> n;
	
	div(290000);
	
	int res = 0;
	for (int i = 0; i < prime.size(); i ++)
		for (int j = i + 1; j < prime.size() && prime[j] * prime[i] <= 1e6; j ++)
		{
			int l = j + 1, r = prime.size() - 1, t = 0;
			while (l <= r)
			{
				int mid = l + r + 1 >> 1;
				if (prime[mid] * prime[i] <= 1e6 && (int)1ll * prime[i] * prime[j] * prime[mid] * prime[i] * prime[mid] <= n) l = mid + 1;
				else r = mid - 1;
			}
			
			res += l - j - 1;
		}
		
	cout << res << endl;
	return 0;
}

E - Dice Product 3

原题

Problem Statement

You have an integer 1 1 1 and a die that shows integers between 1 1 1 and 6 6 6 (inclusive) with equal probability.

You repeat the following operation while your integer is strictly less than N N N:

  • Cast a die. If it shows x x x, multiply your integer by x x x.

Find the probability, modulo 998244353 998244353 998244353, that your integer ends up being N N N.

How to find a probability modulo 998244353 998244353 998244353?
We can prove that the sought probability is always rational.
Additionally, under the constraints of this problem, when that value is represented as P Q \frac{P}{Q} QP with two coprime integers P P P and Q Q Q, we can prove that there is a unique integer R R R such that R × Q ≡ P ( m o d 998244353 ) R \times Q \equiv P\pmod{998244353} R×QP(mod998244353) and 0 ≤ R < 998244353 0 \leq R \lt 998244353 0R<998244353. Find this R R R.

Constraints

2 ≤ N ≤ 1 0 18 2 \leq N \leq 10^{18} 2N1018
N N N is an integer.

Input

The input is given from Standard Input in the following format:

$N$

Output

Print the probability, modulo 998244353 998244353 998244353, that your integer ends up being N N N.

Sample Input 1

6

Sample Output 1

239578645

One of the possible procedures is as follows.
Initially, your integer is 1 1 1.
You cast a die, and it shows 2 2 2. Your integer becomes 1 × 2 = 2 1 \times 2 = 2 1×2=2.
You cast a die, and it shows 4 4 4. Your integer becomes 2 × 4 = 8 2 \times 4 = 8 2×4=8.
Now your integer is not less than 6 6 6, so you terminate the procedure.
Your integer ends up being 8 8 8, which is not equal to N = 6 N = 6 N=6.
The probability that your integer ends up being 6 6 6 is 7 25 \frac{7}{25} 257. Since 239578645 × 25 ≡ 7 ( m o d 998244353 ) 239578645 \times 25 \equiv 7 \pmod{998244353} 239578645×257(mod998244353), print 239578645 239578645 239578645.

Sample Input 2

7

Sample Output 2

0

No matter what the die shows, your integer never ends up being 7 7 7.

Sample Input 3

300

Sample Output 3

183676961

Sample Input 4

979552051200000000

Sample Output 4

812376310

题目大意

这道题的意思筛骰子,筛到每个数(即1-6)的概率均等,把所筛到的数相乘记作 T T T,筛到 T = N T=N T=N的概率是多少


思路

这道题可以想到DP,这里先给出一个简单的DP转移方程:
d p [ x ] = 1 5 ∑ i = 2 6 d p [ i × x ] dp[x]=\frac{1}{5}\displaystyle \sum_{i=2}^{6}dp[i \times x] dp[x]=51i=26dp[i×x]
证明:
d p [ x ] = 1 6 d p [ 1 × x ] + 1 6 ∑ i = 2 6 d p [ i × x ] d p [ x ] − 1 6 d p [ 1 × x ] = 1 6 ∑ i = 2 6 d p [ i × x ] 5 6 d p [ x ] = 1 6 ∑ i = 2 6 d p [ i × x ] 5 6 d p [ x ] ÷ 5 6 = 1 6 ∑ i = 2 6 d p [ i × x ] ÷ 5 6 d p [ x ] = 1 5 ∑ i = 2 6 d p [ i × x ] \begin{equation*} \begin{split} & dp[x] = \frac{1}{6}dp[1\times x] + \frac{1}{6}\displaystyle \sum_{i=2}^{6}dp[i\times x]\\ & dp[x]-\frac{1}{6}dp[1\times x]=\frac{1}{6}\displaystyle \sum_{i=2}^{6}dp[i\times x]\\ & \frac{5}{6}dp[x]=\frac{1}{6}\displaystyle \sum_{i=2}^{6}dp[i\times x]\\ & \frac{5}{6}dp[x]\div \frac{5}{6}=\frac{1}{6}\displaystyle \sum_{i=2}^{6}dp[i\times x]\div \frac{5}{6}\\ & dp[x]=\frac{1}{5}\displaystyle \sum_{i=2}^{6}dp[i \times x] \end{split} \end{equation*} dp[x]=61dp[1×x]+61i=26dp[i×x]dp[x]61dp[1×x]=61i=26dp[i×x]65dp[x]=61i=26dp[i×x]65dp[x]÷65=61i=26dp[i×x]÷65dp[x]=51i=26dp[i×x]

但是,由于N很大,所以这样直接做肯定会TLE
所以,我们想一想,因为有些数是不能被乘出来的,所以我们考虑哪些数会被乘出来!

因为乘的数只能是 2 , 3 , 4 , 5 , 6 2,3,4,5,6 2,3,4,5,6,所以其实就相当于只能是 2 , 3 , 5 2, 3, 5 2,3,5的幂。
即:分解质因数后有且仅有 2 , 3 , 5 2,3,5 2,3,5这三个数(数量没关系)

那么分别考虑:
若是2的幂:则只会有 log ⁡ 2 1 0 18 \log_210^{18} log21018
若是3的幂:则只会有 log ⁡ 3 1 0 18 \log_310^{18} log31018
若是5的幂:则只会有 log ⁡ 5 1 0 18 \log_510^{18} log51018

所以最多只会有: log ⁡ 2 1 0 18 × log ⁡ 3 1 0 18 × log ⁡ 5 1 0 18 \log_210^{18}\times \log_310^{18} \times \log_510^{18} log21018×log31018×log51018

时间复杂度肯定是可以接受的!

由于要考虑边界情况,所以我们可以用记忆化搜索来写,写的会简单点。对于题目中的 R × Q ≡ P ( m o d 998244353 ) R \times Q \equiv P\pmod{998244353} R×QP(mod998244353) and 0 ≤ R < 998244353 0 \leq R \lt 998244353 0R<998244353,由于模数是质数,所以直接用快速幂求就行!

最后,输出的答案即为 d p [ 1 ] dp[1] dp[1],由于我们相当于倒着转移的。


代码

#include 
#include 
#define int long long

using namespace std;

const int MOD = 998244353;

int n, IE5;
unordered_map<int, int> val;

inline int dp(int x)
{
	if (x > n) return 0;
	else if (x == n) return 1;
	else if (val.count((x))) return val[x];
	
	int res = 0;
	for (int i = 2; i <= 6; i ++) res += dp(i * x);
	
	res = res * IE5 % MOD;
	val[x] = res;
	
	return val[x]; 
}

int qmi(int a, int b)
{
	int res = 1;
	
	while (b)
	{
		if (b & 1) res = res * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	
	return res;
}

void init()
{
	IE5 = qmi(5, MOD - 2);
}

signed main()
{
	init();
	
	cin >> n;
	
	cout << dp(1) << endl;
}

F - More Holidays

原题

Problem Statement

You are given a string S S S of length N N N consisting of o and x, and integers M M M and K K K.

S S S is guaranteed to contain at least one x.
Let T T T be the string of length N M NM NM obtained by concatenating M M M copies of S S S.
Consider replacing exactly K K K x's in T T T with o.

Your objective is to have as long a contiguous substring consisting of o as possible in the resulting T T T.

Find the maximum length of a contiguous substring consisting of o that you can obtain.

Constraints

N N N, M M M, and K K K are integers.
1 ≤ N ≤ 3 × 1 0 5 1 \le N \le 3 \times 10^5 1N3×105
1 ≤ M ≤ 1 0 9 1 \le M \le 10^9 1M109
1 ≤ K ≤ x 1 \le K \le x 1Kx, where x x x is the number of x's in the string T T T.
S S S is a string of length N N N consisting of o and x.
S S S has at least one x.

Input

The input is given from Standard Input in the following format:

N N N M M M K K K
S S S

Output

Print the answer as an integer.

Sample Input 1

10 1 2
ooxxooooox

Sample Output 1

9

S = S= S= ooxxooooox and T = T= T= ooxxooooox.

Replacing x at the third and fourth characters with o makes T = T= T= ooooooooox.

Now we have a length- 9 9 9 contiguous substring consisting of o, which is the longest possible.

Sample Input 2

5 3 4
oxxox

Sample Output 2

8

S = S= S= oxxox and T = T= T= oxxoxoxxoxoxxox.

Replacing x at the 5 , 7 , 8 5,7,8 5,7,8 and 10 10 10-th characters with o makes T = T= T= oxxooooooooxxox.

Now we have a length- 8 8 8 contiguous substring consisting of o, which is the longest possible.

Sample Input 3

30 1000000000 9982443530
oxoxooxoxoxooxoxooxxxoxxxooxox

Sample Output 3

19964887064

题目大意

字符串S由xo组成,长度是N,M表示一共M个字符串S连接组成一个新的S,K表示在新的S中修改K个xo,问S中最长o相连的子串的长度。


思路

因为S是M个重复字符串(每个长度为N)组成,所以如果第一个要改变的x一定在前N个字符中,此时可以有两种方法来做这个题。

方法一:

硬算,比赛时我就是硬算的,结果算的不对,导致时间不足了。

方法二:

采用遍历加二分的方法来完成。
1、对原始的S做一次前缀和,计算去前i个字符中x的个数。
2、对原始的S反过来再计算一次前缀和,计算第i个字符后x的个数。
3、计算原始的S共有多少个x,设为p
4、如果K > p,那么 NM长度的新S中K / p 个原S中的x都要转为o,K % p的x就要从前面的第一个S和后面的S中截取。所以只需要计算从第一个S中的第i位开始截取,到后面S的哪一位结束就可以了。这个过程,可以用二分来完成。

注意:求x个数的公式一定要仔细推,很容易推错!

写的简略了点,有问题可以问我!

代码

#include 
#define int long long

using namespace std;

const int N = 3e5 + 10;

int n, m, k, p;
int frw[N], rvs[N];
string s;

bool check(int l, int r)
{
	int num_x = (r <= n) ? frw[r] - frw[l - 1] : rvs[l] + frw[r % n] + (r - n) / n * p;
	
	return num_x <= k;
}

signed main()
{
	cin >> n >> m >> k >> s;
	
	s = ' ' + s;
	for (int i = 1; i <= n; i ++)
		frw[i] = frw[i - 1] + (s[i] == 'x'), p += (s[i] == 'x');
		
	for (int i = n; i >= 1; i --)
		rvs[i] = rvs[i + 1] + (s[i] == 'x');
		
	int res = 0;
	for (int i = 1; i <= n; i ++)
	{
		int l = i, r = n * m;
		while (l < r)
		{
			int mid = l + r + 1 >> 1;
			if (check(i, mid)) l = mid;
			else r = mid - 1;
		}
		res = max(res, l - i + 1);
	}
	
	cout << res << endl;
}

G - P-smooth number

原题

Problem Statement

A positive integer is called a k k k-smooth number if none of its prime factors exceeds k k k.

Given an integer N N N and a prime P P P not exceeding 100 100 100, find the number of P P P-smooth numbers not exceeding N N N.

Constraints

N N N is an integer such that 1 ≤ N ≤ 1 0 16 1 \le N \le 10^{16} 1N1016.
P P P is a prime such that 2 ≤ P ≤ 100 2 \le P \le 100 2P100.

Input

The input is given from Standard Input in the following format:
N N N P P P

Output

Print the answer as an integer.

Sample Input 1

36 3

Sample Output 1

14

The 3 3 3-smooth numbers not exceeding 36 36 36 are the following 14 14 14 integers: 1 , 2 , 3 , 4 , 6 , 8 , 9 , 12 , 16 , 18 , 24 , 27 , 32 , 36 1,2,3,4,6,8,9,12,16,18,24,27,32,36 1,2,3,4,6,8,9,12,16,18,24,27,32,36.

Note that 1 1 1 is a k k k-smooth number for all primes k k k.

Sample Input 2

10000000000000000 97

Sample Output 2

2345134674

题目大意

计算N以内所有P的平滑数有多少个,其中P不超过100。
平滑数的定义:一个质因子不超过K的数,叫做K的平滑数。


思路

学习了一下官方的思路,这个题采用双向搜索(meet-in-the-middle trick),先从两端开始搜索,然后将结果放入两个集合中,最后将两个集合的混合计算。

注意:1是一个特殊的,永远是平滑数!

写的简略了点,有问题可以问我!


代码

#include 
#include 
#include 
#define int long long

using namespace std;

int n, p;

void push(vector<int> &a, int num)
{
	int sz = a.size();
	for (int i = 0; i < sz; i ++)
	{
		int t = a[i];
		while (1)
		{
			t *= num;
			if (t > n) break;
			a.push_back(t);
		}
	}
}

signed main()
{
	vector<int> prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
	
	cin >> n >> p;
	
	while (p < prime.back()) prime.pop_back();
	
	vector<int> frt = {1}, bck = {1};
	for (auto &c : prime)
		if (frt.size() < bck.size()) push(frt, c);
		else push(bck, c);
		
	sort(frt.begin(), frt.end());
	sort(bck.begin(), bck.end());
	
	int res = 0;
	for (int i = 0, j = bck.size() - 1; i < frt.size(); i ++)
	{
		int left = n / frt[i];
		while (j >= 0 && left < bck[j]) j --;
		if (j < 0) break;
		res += j + 1;
	}
	
	cout << res << endl;
}

本次题解的E题得到了国家队大佬刘一平老师的指点,感谢刘老师。

因为最近感冒,所以拖到现在才更新。

今天就到这里了!

大家有什么问题尽管提,我都会尽力回答的!

吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!

你可能感兴趣的:(数学,算法-二分,算法-搜索,算法,c++)