AtCoder Beginner Contest 293——A-E题讲解

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

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

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

A - Swap Odd and Even

原题

Problem Statement

You are given a string S S S of even length consisting of lowercase English letters. Let ∣ S ∣ |S| S be the length of S S S, and S i S_i Si be the i i i-th character of S S S.
Perform the following operation for each i = 1 , 2 , … , ∣ S ∣ 2 i = 1, 2, \ldots, \frac{|S|}{2} i=1,2,,2S in this order, and print the final S S S.
Swap S 2 i − 1 S_{2i-1} S2i1 and S 2 i S_{2i} S2i.

Constraints

S S S is a string of even length consisting of lowercase English letters.
The length of S S S is at most 100 100 100.

Input

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

Output

Print the answer.

Sample Input 1

abcdef

Sample Output 1

badcfe
Initially, S = S = S= abcdef.

Performing the operation for i = 1 i = 1 i=1 swaps S 1 S_1 S1 and S 2 S_2 S2, making S = S = S= bacdef.

Performing the operation for i = 2 i = 2 i=2 swaps S 3 S_3 S3 and S 4 S_4 S4, making S = S = S= badcef.

Performing the operation for i = 3 i = 3 i=3 swaps S 5 S_5 S5 and S 6 S_6 S6, making S = S = S= badcfe.

Thus, badcfe should be printed.

Sample Input 2

aaaa

Sample Output 2

aaaa

Sample Input 3

atcoderbeginnercontest

Sample Output 3

taocedbrgeniencrnoetts


题目大意

本题就是给出一个字符串,交换 S 2 i − 1 S_{2i-1} S2i1 S 2 i S_{2i} S2i i = 1 , 2 , … , ∣ S ∣ 2 i = 1, 2, \ldots, \frac{|S|}{2} i=1,2,,2S


思路

用swap交换一下就行,过于简单,不再多说~~~


代码

#include <iostream>
#define endl '\n'
#define pb(i) push_back(i)

using namespace std;

inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    string s;
    
    cin >> s;
    
    s = ' ' + s;
    for (int i = 1; i <= (int)s.size() / 2; i ++)
    	swap(s[2 * i - 1], s[2 * i]);
    	
    s.erase(0, 1);
    cout << s << endl;
    
    return 0;
}

B - Call the ID Number

原题

Problem Statement

There are N N N people whose IDs are 1 1 1, 2 2 2, … \ldots , and N N N.
Each of person 1 1 1, person 2 2 2, … \ldots , and person N N N performs the following action once in this order:
If person i i i’s ID has not been called out yet, call out person A i A_i Ai’s ID.
Enumerate the IDs of all the people whose IDs are never called out until the end in ascending order.

Constraints

2 ≤ N ≤ 2 × 1 0 5 2 \leq N \leq 2 \times 10^5 2N2×105
1 ≤ A i ≤ N 1 \leq A_i \leq N 1AiN
A i ≠ i A_i \neq i Ai=i
All values in the input are integers.

Input

The input is given from Standard Input in the following format:
N N N
A 1 A_1 A1 A 2 A_2 A2 … \ldots A N A_N AN

Output

Enumerate the IDs of all the people whose IDs are not called out until the end in ascending order in the following format:
K K K
X 1 X_1 X1 X 2 X_2 X2 … \ldots X K X_K XK
In other words, the first line should contain the number of people, K K K, whose IDs are never called out until the end;
the second line should contain the sequence ( X 1 , X 2 , … , X K ) (X_1, X_2, \ldots, X_K) (X1,X2,,XK) of IDs of such people in ascending order, with spaces in between.

Sample Input 1

5
3 1 4 5 4

Sample Output 1

2
2 4
The five people’s actions are as follows.
Person 1 1 1’s ID has not been called out yet, so person 1 1 1 calls out person 3 3 3’s ID.
Person 2 2 2’s ID has not been called out yet, so person 2 2 2 calls out person 1 1 1’s ID.
Person 3 3 3’s ID has already been called out by person 1 1 1, so nothing happens.
Person 4 4 4’s ID has not been called out yet, so person 4 4 4 calls out person 5 5 5’s ID.
Person 5 5 5’s ID has already been called out by person 4 4 4, so nothing happens.
Therefore, person 2 2 2 and 4 4 4’s IDs are not called out until the end.

Sample Input 2

20
9 7 19 7 10 4 13 9 4 8 10 15 16 3 18 19 12 13 2 12

Sample Output 2

10
1 2 5 6 8 11 14 17 18 20


题目大意

本题就是对于每一个人(当他没有叫走时)他可以叫走第 A i A_i Ai个人,最后问你有多少个人没被叫走,并输出编号


思路

直接暴力一遍即可


代码

#include <iostream>
#include <vector>
#define endl '\n'
#define pb(i) push_back(i)

using namespace std;

const int N = 2e5 + 10;

int n;
bool st[N];
int a[N];

inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    cin >> n;
    
    for (int i = 1; i <= n; i ++)
    	cin >> a[i];
    
    for (int i = 1; i <= n; i ++)
    	if (!st[i])
    		st[a[i]] = 1;
    		
    int res = 0;
    vector<int> ans;
    for (int i = 1; i <= n; i ++)
    	if (st[i] == 0)
    	{
    		res ++;
    		ans.pb(i);
    	}
    	
    cout << res << endl;
    for (auto c :ans)
    	cout << c << " ";
    
    return 0;
}

C - Make Takahashi Happy

原题

Problem Statement

There is a grid with H H H horizontal rows and W W W vertical columns.
For two integers i i i and j j j such that 1 ≤ i ≤ H 1 \leq i \leq H 1iH and 1 ≤ j ≤ W 1 \leq j \leq W 1jW,
the square at the i i i-th row from the top and j j j-th column from the left (which we denote by ( i , j ) (i, j) (i,j)) has an integer A i , j A_{i, j} Ai,j written on it.
Takahashi is currently at ( 1 , 1 ) (1,1) (1,1).
From now on, he repeats moving to an adjacent square to the right of or below his current square until he reaches ( H , W ) (H, W) (H,W).
When he makes a move, he is not allowed to go outside the grid.
Takahashi will be happy if the integers written on the squares he visits (including initial ( 1 , 1 ) (1, 1) (1,1) and final ( H , W ) (H, W) (H,W)) are distinct.
Find the number of his possible paths that make him happy.

Constraints

2 ≤ H , W ≤ 10 2 \leq H, W \leq 10 2H,W10
1 ≤ A i , j ≤ 1 0 9 1 \leq A_{i, j} \leq 10^9 1Ai,j109
All values in the input 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, 1} A1,1 A 1 , 2 A_{1, 2} A1,2 … \ldots A 1 , W A_{1, W} A1,W
A 2 , 1 A_{2, 1} A2,1 A 2 , 2 A_{2, 2} A2,2 … \ldots A 2 , W A_{2, W} A2,W
⋮ \vdots
A H , 1 A_{H, 1} AH,1 A H , 2 A_{H, 2} AH,2 … \ldots A H , W A_{H, W} AH,W

Output

Print the answer.

Sample Input 1

3 3
3 2 2
2 1 3
1 5 4

Sample Output 1

3
There are six possible paths:
( 1 , 1 ) → ( 1 , 2 ) → ( 1 , 3 ) → ( 2 , 3 ) → ( 3 , 3 ) (1, 1) \rightarrow (1, 2) \rightarrow (1, 3) \rightarrow (2, 3) \rightarrow (3, 3) (1,1)(1,2)(1,3)(2,3)(3,3): the integers written on the squares he visits are 3 , 2 , 2 , 3 , 4 3, 2, 2, 3, 4 3,2,2,3,4, so he will not be happy.
( 1 , 1 ) → ( 1 , 2 ) → ( 2 , 2 ) → ( 2 , 3 ) → ( 3 , 3 ) (1, 1) \rightarrow (1, 2) \rightarrow (2, 2) \rightarrow (2, 3) \rightarrow (3, 3) (1,1)(1,2)(2,2)(2,3)(3,3): the integers written on the squares he visits are 3 , 2 , 1 , 3 , 4 3, 2, 1, 3, 4 3,2,1,3,4, so he will not be happy.
( 1 , 1 ) → ( 1 , 2 ) → ( 2 , 2 ) → ( 3 , 2 ) → ( 3 , 3 ) (1, 1) \rightarrow (1, 2) \rightarrow (2, 2) \rightarrow (3, 2) \rightarrow (3, 3) (1,1)(1,2)(2,2)(3,2)(3,3): the integers written on the squares he visits are 3 , 2 , 1 , 5 , 4 3, 2, 1, 5, 4 3,2,1,5,4, so he will be happy.
( 1 , 1 ) → ( 2 , 1 ) → ( 2 , 2 ) → ( 2 , 3 ) → ( 3 , 3 ) (1, 1) \rightarrow (2, 1) \rightarrow (2, 2) \rightarrow (2, 3) \rightarrow (3, 3) (1,1)(2,1)(2,2)(2,3)(3,3): the integers written on the squares he visits are 3 , 2 , 1 , 3 , 4 3, 2, 1, 3, 4 3,2,1,3,4, so he will not be happy.
( 1 , 1 ) → ( 2 , 1 ) → ( 2 , 2 ) → ( 3 , 2 ) → ( 3 , 3 ) (1, 1) \rightarrow (2, 1) \rightarrow (2, 2) \rightarrow (3, 2) \rightarrow (3, 3) (1,1)(2,1)(2,2)(3,2)(3,3): the integers written on the squares he visits are 3 , 2 , 1 , 5 , 4 3, 2, 1, 5, 4 3,2,1,5,4, so he will be happy.
( 1 , 1 ) → ( 2 , 1 ) → ( 3 , 1 ) → ( 3 , 2 ) → ( 3 , 3 ) (1, 1) \rightarrow (2, 1) \rightarrow (3, 1) \rightarrow (3, 2) \rightarrow (3, 3) (1,1)(2,1)(3,1)(3,2)(3,3): the integers written on the squares he visits are 3 , 2 , 1 , 5 , 4 3, 2, 1, 5, 4 3,2,1,5,4, so he will be happy.
Thus, the third, fifth, and sixth paths described above make him happy.

Sample Input 2

10 10
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100

Sample Output 2

48620
In this example, every possible path makes him happy.


题目大意

本题就是从左上角走到右下角,途中不经过相同数字的点的个数,问有多少种满足条件的路径!


思路

这道题我么可以直接用DFS深搜一遍即可,相信大家都会DFS了所以就不过多赘述(有不会的,可以私聊我!)


代码

#include <iostream>
#include <unordered_map>
#define endl '\n'
#define pb(i) push_back(i)

using namespace std;

const int N = 2e1 + 10;

int n, m;
int a[N][N];
unordered_map<int, int> st;
int dx[2] = {1, 0}, dy[2] = {0, 1};
int res = 0;

inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}

void dfs(int x, int y)
{
	if (x == n && y == m)
	{
		res ++;
		return;
	}
	
	for (int i = 0; i < 2; i ++)
	{
		int xx = x + dx[i], yy = y + dy[i];
		if (xx < 1 || yy < 1 || xx > n || yy > m || st[a[xx][yy]]) continue;
		
		st[a[xx][yy]] = 1;
		dfs(xx, yy);
		st[a[xx][yy]] = 0;
	}
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++)
    	for (int j = 1; j <= m; j ++)
    		cin >> a[i][j];
    		
    st[a[1][1]] = 1;
    dfs(1, 1);
    
    cout << res << endl;
    
    return 0;
}

D - Tying Rope(毒瘤!!!)

原题

Problem Statement

There are N N N ropes numbered 1 1 1 through N N N. One end of each rope is painted red, and the other is painted blue.
You are going to perform M M M operations of tying ropes. In the i i i-th operation, you tie the end of rope A i A_i Ai painted B i B_i Bi with the end of rope C i C_i Ci painted D i D_i Di, where R means red and B means blue. For each rope, an end with the same color is not tied multiple times.
Find the number of groups of connected ropes that form cycles, and the number of those that do not, after all the operations.
Here, a group of connected ropes { v 0 , v 1 , … , v x − 1 } \lbrace v_0, v_1, \ldots, v_{x-1} \rbrace {v0,v1,,vx1} is said to form a cycle if one can rearrange the elements of v v v so that, for each KaTeX parse error: Expected 'EOF', got '&' at position 10: 0 \leq i &̲lt; x, rope v i v_i vi is tied to rope v ( i + 1 )   m o d   x v_{(i+1) \bmod x} v(i+1)modx.

Constraints

1 ≤ N ≤ 2 × 1 0 5 1 \leq N \leq 2 \times 10^5 1N2×105
0 ≤ M ≤ 2 × 1 0 5 0 \leq M \leq 2 \times 10^5 0M2×105
1 ≤ A i , C i ≤ N 1 \leq A_i, C_i \leq N 1Ai,CiN
( A i , B i ) ≠ ( A j , B j ) , ( C i , D i ) ≠ ( C j , D j ) (A_i, B_i) \neq (A_j, B_j), (C_i, D_i) \neq (C_j, D_j) (Ai,Bi)=(Aj,Bj),(Ci,Di)=(Cj,Dj) ( i ≠ j ) (i \neq j) (i=j)
( A i , B i ) ≠ ( C j , D j ) (A_i, B_i) \neq (C_j, D_j) (Ai,Bi)=(Cj,Dj)
N , M , A i N, M, A_i N,M,Ai, and C i C_i Ci are integers.
B i B_i Bi is R or B, and so is D i D_i Di.

Input

The input is given from Standard Input in the following format:
N N N M M M
A 1 A_1 A1 B 1 B_1 B1 C 1 C_1 C1 D 1 D_1 D1
A 2 A_2 A2 B 2 B_2 B2 C 2 C_2 C2 D 2 D_2 D2
⋮ \vdots
A M A_M AM B M B_M BM C M C_M CM D M D_M DM

Output

Print X X X and Y Y Y in this order, separated by a space, where X X X is the number of groups of connected ropes that form cycles, and Y Y Y is the number of those that do not.

Sample Input 1

5 3
3 R 5 B
5 R 3 B
4 R 2 B

Sample Output 1

1 2
There are three groups of connected ropes: { 1 } \lbrace 1 \rbrace {1}, { 2 , 4 } \lbrace 2,4 \rbrace {2,4}, and { 3 , 5 } \lbrace 3,5 \rbrace {3,5}.
The group of ropes { 3 , 5 } \lbrace 3,5 \rbrace {3,5} forms a cycle, while the groups of rope { 1 } \lbrace 1 \rbrace {1} and ropes { 2 , 4 } \lbrace 2,4 \rbrace {2,4} do not. Thus, X = 1 X = 1 X=1 and Y = 2 Y = 2 Y=2.

Sample Input 2

7 0

Sample Output 2

0 7

Sample Input 3

7 6
5 R 3 R
7 R 4 R
4 B 1 R
2 R 3 B
2 B 5 B
1 B 7 B

Sample Output 3

2 1


题目大意

这题太恶心了!跟颜色压根没关系!这道题就是将绳子 A i A_i Ai C i C_i Ci连在一起,最后判断有多少个连通块是环,有多少个不是环!


思路

首先刚才也说了跟颜色没关系,所以我们就大胆的判断有多少个换就行了(不会可以看判断图中存在闭环的常用方法,本题我用的并查集的方法并查集只限于无向图),那不是换的怎么算呢?我们可以用到Flood Fill算法计算有多少个连通块,再用连通块的数量减去有环的连通块的数量即为非环的数量!


代码

#include <iostream>
#include <vector>
#define endl '\n'
#define pb(i) push_back(i)

using namespace std;

const int N = 2e5 + 10;

int p[N];
int st[N];
bool flg;
vector<int> g[N];

inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}

int find(int x)
{
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}

void dfs(int u)
{	
	st[u] = 1;
	for (auto c : g[u])
		if (!st[c])
			dfs(c);
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    int n, m;
    
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++)
    	p[i] = i;
    
    int u, q, x = 0, y =0 ;
    char gun1, gun2;
    for (int i = 1; i <= m; i ++)
    {
    	cin >> u >> gun1 >> q >> gun2;
    	//建边
    	g[u].pb(q);
    	g[q].pb(u);
    	
    	if (find(u) == find(q)) //有环了!
    		x ++;
    	else p[find(u)] = find(q); //合并集合
    	
    }
    //计算连通块的数量
    int res = 0;
    for (int i = 1; i <= n; i ++)
    	if (!st[i])
    	{
    		dfs(i);
    		res ++;
    	}
    		
    cout << x << " " << res - x << endl;
    
    return 0;
}

E - Geometric Progression(重头戏)

原题

Problem Statement

Given integers A A A, X X X, and M M M, find ∑ i = 0 X − 1 A i \displaystyle \sum_{i = 0}^{X-1} A^i i=0X1Ai, modulo M M M.

Constraints

1 ≤ A , M ≤ 1 0 9 1 \leq A, M \leq 10^9 1A,M109
1 ≤ X ≤ 1 0 12 1 \leq X \leq 10^{12} 1X1012
All values in the input are integers.

Input

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

Output

Print the answer.

Sample Input 1

3 4 7

Sample Output 1

5
3 0 + 3 1 + 3 2 + 3 3 = 40 3^0 + 3^1 + 3^2 + 3^3 = 40 30+31+32+33=40, which equals 5 5 5 modulo 7 7 7, so 5 5 5 should be printed.

Sample Input 2

8 10 9

Sample Output 2

0

Sample Input 3

1000000000 1000000000000 998244353

Sample Output 3

919667211


题目大意

就是算出 ∑ i = 0 X − 1 A i \displaystyle \sum_{i = 0}^{X-1} A^i i=0X1Ai, 模 M M M的值


思路

∑ i = 0 X − 1 A i \displaystyle \sum_{i = 0}^{X-1} A^i i=0X1Ai等于 A 0 + A 1 + ⋯ + A x − 2 + A x − 1 A^0 + A^1 + \dots + A^{x-2} + A^{x-1} A0+A1++Ax2+Ax1,此时就发现其实就是将A进制数下的 1111111 … 111 1111111\dots 111 1111111111转为十进制数。

t t t X − 1 X-1 X1
那么 t t t一定可以分解为 ( 111 … 111 ) 2 、 ( 111 ) 2 、 … 、 2 1 、 2 0 (111\dots111)_2 、(111)_2、\dots、2^1、2^0 (111111)2(111)22120这些数中某几个数的和!

浅浅的证明:

因为2^0是1,所以任何数至少可以分成好几个1相加!

之后我们可以转化为:
∑ i = 0 t A i = A 0 + A 1 + ⋯ + A t − 1 + A t = ( 1 + A ( 1 ) 2 + A ( 10 ) 2 + A ( 11 ) 2 + ⋯ + A ( 11 … 111 ( s − 1 个 ) ) 2 + A ( 10 … 001 ) 2 + … = ∑ i = 0 s − 1 A i + ∑ i = s y − 1 A i + ∑ i = y z − 1 A i + … = ∑ i = 0 s − 1 A i + A s ∑ i = 0 y − s − 1 A i + A y ∑ i = 0 z − y − 1 A i + … \begin{align*} \displaystyle \sum_{i = 0}^{t} A^i&= A^0 + A^1 + \dots + A^{t-1} + A^{t} \\ &= (1+A^{(1)_2}+A^{(10)_2}+A^{(11)_2}+\dots+A^{(11\dots111(s-1个))_2} + A^{(10\dots001)_2}+\dots\\ &= \displaystyle \sum_{i = 0}^{s-1} A^i + \displaystyle \sum_{i = s}^{y - 1} A^i + \displaystyle \sum_{i = y}^{z - 1} A^i + \dots \\ &=\displaystyle \sum_{i = 0}^{s - 1} A^i + A^s\displaystyle \sum_{i = 0}^{y - s - 1} A^i + A^y\displaystyle \sum_{i = 0}^{z-y-1} A^i+\dots \end{align*} i=0tAi=A0+A1++At1+At=(1+A(1)2+A(10)2+A(11)2++A(11111(s1))2+A(10001)2+=i=0s1Ai+i=sy1Ai+i=yz1Ai+=i=0s1Ai+Asi=0ys1Ai+Ayi=0zy1Ai+
这里 s − 1 , y − s − 1 , z − y − 1 s-1,y-s-1,z-y-1 s1,ys1,zy1全是 ( 111 … 111 ) 2 (111\dots111)_2 (111111)2或0,如:
∑ i = 0 11 A i = A 0 + A 1 + ⋯ + A 10 + A 11 = ∑ i = 0 7 A i + ∑ i = 8 11 A i = ∑ i = 0 7 A i + A 8 ∑ i = 0 3 A i \begin{align*} \displaystyle \sum_{i = 0}^{11} A^i&= A^0 + A^1 + \dots + A^{10} + A^{11} \\ &= \displaystyle \sum_{i = 0}^{7} A^i + \displaystyle \sum_{i = 8}^{11} A^i\\ &=\displaystyle \sum_{i = 0}^{7} A^i + A^8\displaystyle \sum_{i = 0}^{3} A^i \end{align*} i=011Ai=A0+A1++A10+A11=i=07Ai+i=811Ai=i=07Ai+A8i=03Ai

所以,我们可以先把这个 ∑ i = 0 0 A i , ∑ i = 0 1 A i , ∑ i = 0 3 A i , ∑ i = 0 7 A i , … \displaystyle \sum_{i = 0}^{0} A^i,\displaystyle \sum_{i = 0}^{1} A^i,\displaystyle \sum_{i = 0}^{3} A^i,\displaystyle \sum_{i = 0}^{7} A^i,\dots i=00Aii=01Aii=03Aii=07Ai预处理出来!
那么预处理到多少呢?
答案是: 2 39 − 1 2^{39}-1 2391
因为x小于等于 1 0 12 10^{12} 1012,而 2 40 − 1 2^{40}-1 2401大于 1 0 12 10^{12} 1012,所以处理到 2 39 − 1 2^{39}-1 2391就可以了

那么怎么计算呢?
我们先处理出 ∑ i = 0 0 A i \displaystyle \sum_{i = 0}^{0} A^i i=00Ai,就是1!然后我们递推的求出之后的每一个。
递推公式:(t为当前算第几个数)
∑ i = 0 2 t − 1 A i = ∑ i = 0 2 ( t − 1 ) − 1 A i × ( A 2 t − 1 + 1 ) \begin{align*} \displaystyle \sum_{i = 0}^{2^t-1} A^i = \displaystyle \sum_{i = 0}^{2^{(t - 1)}-1} A^i \times (A^{2^{t-1}} + 1) \end{align*} i=02t1Ai=i=02(t1)1Ai×(A2t1+1)

然后,我们发现是s, y, z,都是2的整数次幂,所以我们也提前与处理出来 A 2 0 , A 2 1 , … , A 2 39 A^{2^0},A^{2^1},\dots,A^{2^{39}} A20,A21,,A239就可以了!

最后,按照公式加起来就可以了!

注意:

  1. 要用long long
  2. 注意不能用 1 < < 1<< 1<<,因为超过32时,会出错(亲测)
  3. 要用快速幂!

相信大家都不喜欢看长长的证明,那么香香的代码送你们了


代码

#include <iostream>
#include <cmath>
#include <deque>
#define int long long
#define endl '\n'
#define pb(i) push_back(i)

using namespace std;

inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}

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

signed main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
	int a, x, m;
	
	cin >> a >> x >> m;
	
	deque<int> sgm, pw;
	//预处理
	sgm.pb(1);
	pw.pb(a % m);
	while (sgm.size() < 40)
		sgm.pb(sgm.back() * (qmi(a, (int)pow(2, sgm.size() - 1), m) + 1) % m);
	while (pw.size() < 40)
		pw.pb(pw.back() * pw.back() % m);
	//计算
    int res = 0, times = 1;
    for (int i = 39; i >= 0; i --)
    {
    	int t = pow(2, i);
    	if (x >= t)
    	{
    		
    		res = (res + (sgm[i] * times % m)) % m;
    		times = times * pw[i] % m;
    		x -= t;
    	}
    }	
	cout << res << endl;
    
    return 0;
}

今天就到这里了!

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

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

(这两天比赛有点多,直到现在才发出来,非常抱歉~~~)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值