AtCoder Beginner Contest 296——D-E

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

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

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

D - M<=ab

原题

Problem Statement

You are given positive integers N N N and M M M.

Find the smallest positive integer X X X that satisfies both of the conditions below, or print − 1 -1 1 if there is no such integer.
X X X can be represented as the product of two integers a a a and b b b between 1 1 1 and N N N, inclusive. Here, a a a and b b b may be the same.
X X X is at least M M M.

Constraints

1 ≤ N ≤ 1 0 12 1\leq N\leq 10^{12} 1N1012
1 ≤ M ≤ 1 0 12 1\leq M\leq 10^{12} 1M1012
N N N and M M M are integers.

Input

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

Output

Print the smallest positive integer X X X that satisfies both of the conditions, or − 1 -1 1 if there is no such integer.

Sample Input 1

5 7

Sample Output 1

8
First, 7 7 7 cannot be represented as the product of two integers between 1 1 1 and 5 5 5.

Second, 8 8 8 can be represented as the product of two integers between 1 1 1 and 5 5 5, such as 8 = 2 × 4 8=2\times 4 8=2×4.
Thus, you should print 8 8 8.

Sample Input 2

2 5

Sample Output 2

-1
Since 1 × 1 = 1 1\times 1=1 1×1=1, 1 × 2 = 2 1\times 2=2 1×2=2, 2 × 1 = 2 2\times 1=2 2×1=2, and 2 × 2 = 4 2\times 2=4 2×2=4, only 1 1 1, 2 2 2, and 4 4 4 can be represented as the product of two integers between 1 1 1 and 2 2 2,
so no number greater than or equal to 5 5 5 can be represented as the product of two such integers.

Thus, you should print − 1 -1 1.

Sample Input 3

100000 10000000000

Sample Output 3

10000000000
For a = b = 100000 a=b=100000 a=b=100000 ( = 1 0 5 ) (=10^5) (=105), the product of a a a and b b b is 10000000000 10000000000 10000000000 ( = 1 0 10 ) (=10^{10}) (=1010), which is the answer.

Note that the answer may not fit into a 32 32 32-bit integer type.


思路

首先,我们可以假定 a ≤ b a \le b ab,这个是跟结果没有什么关系的!(显而易见)

其次,
∵ a ≤ b \because a\le b ab
∴ a b ≥ a 2 \therefore ab \ge a^2 aba2
∵ a b ≥ M , a b 离 M 最近 \because ab \ge M, ab离M最近 abM,abM最近
∴ a b ≥ M ≥ a 2 \therefore ab\ge M\ge a^2 abMa2
∴ a 2 ≤ M \therefore a^2\le M a2M
∴ a ≤ ⌈ M ⌉ \therefore a\le \left \lceil\sqrt{M} \right \rceil aM

所以,要想使ab离M最近,则 b = ⌈ M a ⌉ b = \left \lceil\frac{M}{a}\right \rceil b=aM 1 ≤ a , b ≤ n 1 \le a, b \le n 1a,bn, a b ≥ M ab \ge M abM

满足以上所有条件的a,b即为答案,求出最小的ab就可以了!


代码

#include 
#include 
#include 
#include 
#define int long long
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)

using namespace std;

typedef pair<int, int> PII;

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;
}

signed main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    int n, m;
    
    cin >> n >> m;
    
    int ans = 2e18;
    for (int a = 1; a <= ceil(sqrt(m)); a ++)
    {
    	int b = ceil(m * 1.0 / a);
    	if (b > n || a > n) continue;
    	if (a * b >= m && a * b < ans) ans = a * b;
    }
    
    if (ans == 2e18) cout << -1 << endl;
    else cout << ans << endl;
    
    return 0;
}

E题

原题

Problem Statement

You are given a sequence of N N N numbers: A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\ldots,A_N) A=(A1,A2,,AN). Here, each A i A_i Ai ( 1 ≤ i ≤ N ) (1\leq i\leq N) (1iN) satisfies 1 ≤ A i ≤ N 1\leq A_i \leq N 1AiN.
Takahashi and Aoki will play N N N rounds of a game. For each i = 1 , 2 , … , N i=1,2,\ldots,N i=1,2,,N, the i i i-th game will be played as follows.

  1. Aoki specifies a positive integer $K_i$. After knowing $K_i$ Aoki has specified, Takahashi chooses an integer $S_i$ between $1$ and $N$, inclusive, and writes it on a blackboard. Repeat the following $K_i$ times. Replace the integer $x$ written on the blackboard with $A_x$.
If $i$ is written on the blackboard after the $K_i$ iterations, Takahashi wins the $i$-th round; otherwise, Aoki wins.
Here, $K_i$ and $S_i$ can be chosen independently for each $i=1,2,\ldots,N$. Find the number of rounds Takahashi wins if both players play optimally to win. #### Constraints

1 ≤ N ≤ 2 × 1 0 5 1\leq N\leq 2\times 10^5 1N2×105
1 ≤ A i ≤ N 1\leq A_i\leq N 1AiN
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

Find the number of rounds Takahashi wins if both players play optimally to win.

Sample Input 1

3
2 2 3

Sample Output 1

2
In the first round, if Aoki specifies K 1 = 2 K_1=2 K1=2, Takahashi cannot win whichever option he chooses for S 1 S_1 S1: 1 1 1, 2 2 2, or 3 3 3.
For example, if Takahashi writes S 1 = 1 S_1=1 S1=1 on the initial blackboard, the two operations will change this number as follows: 1 → 2 ( = A 1 ) 1\to 2(=A_1) 12(=A1), 2 → 2 ( = A 2 ) 2\to 2(=A_2) 22(=A2). The final number on the blackboard will be 2 ( ≠ 1 ) 2(\neq 1) 2(=1), so Aoki wins.
On the other hand, in the second and third rounds, Takahashi can win by writing 2 2 2 and 3 3 3, respectively, on the initial blackboard, whatever value Aoki specifies as K i K_i Ki.
Therefore, if both players play optimally to win, Takashi wins two rounds: the second and the third. Thus, you should print 2 2 2.

Sample Input 2

2
2 1

Sample Output 2

2
In the first round, Takahashi can win by writing 2 2 2 on the initial blackboard if K 1 K_1 K1 specified by Aoki is odd, and 1 1 1 if it is even.
Similarly, there is a way for Takahashi to win the second round. Thus, Takahashi can win both rounds: the answer is 2 2 2.


题目大意

有一个N位的序列, A 1 , A 2 … … A N A_1,A_2……A_N A1,A2……AN
Aoki指定一个 K i K_i Ki
然后 Takahashi根据Aoki指定的 k i k_i ki选择一个 s i s_i si,
最后,用 A x A_x Ax来替换 x x x,一共替换 k i k_i ki
如果最后在黑板上的 A x A_x Ax正好是 k i k_i ki i i i,那么 T a k a h a s h i Takahashi Takahashi胜,否则 A o k i Aoki Aoki胜。

以样例1为例:

N=3
A={2,2,3}

情况1 :
Aoki选择 K 1 = 2 K_1 = 2 K1=2,此时轮到 Takahashi选择 s 1 s_1 s1,那么 s 1 s_1 s1可以等1,2或者3.
s 1 = 1 s_1=1 s1=1时,把1写在黑板上, x = 1 x=1 x=1,接下来 k 1 k_1 k1轮替换,第一轮,用 A x A_x Ax替换 x x x,即 A 1 A_1 A1替换1,所以黑板上变成 A 1 A_1 A1即2,第二轮用A2替换2,所以黑板上变成2。最后,因为2不等于 k 1 k_1 k1中的1,所以Aoki胜。
同理,当s1=2时,最终也是2不等于1 ,也是Aoki胜。
S 1 = 3 S_1=3 S1=3时,最终是3不等于1,也是Aoki胜。可以得出结论,对于情况1,Takahashi是不可能胜的,此题目中双方都是最优手,所以只能是Aoki胜。

情况2:
Aoki选择K2 = 2,此时轮到 Takahashi选择s2,那么s2可以等1,2或者3.当Takahashi选择S2=1和2时,Takahashi都会胜,所以在这一情况下,Takahashi一定会选择他胜的方案,最终Takahashi胜。

情况3:
Aoki选择K3 = 3,此时轮到 Takahashi选择s3,那么s3可以等1,2或者3.当Takahashi选择S3=3时,Takahashi会胜,所以在这一情况下,Takahashi一定会选择他胜的方案,最终Takahashi胜。
因为情况2和情况3能胜,所以输出为2.


思路

基于以上分析,本题就是在找Aoki从 a 1 , a 2 … … a n a_1,a_2……a_n a1,a2……an选择时,有几个选择Takahashi方案能胜。

当选中Ki后,对于Takahashi来说,其实就是从1到N中选择一个数,如何能够快速到 A x A_x Ax使得 A x A_x Ax的值为 i i i.可以考虑一个有向图。
如样例1:
A = 2 , 2 , 3 A={2,2,3} A=2,2,3 => 1 − > 2 , 2 − > 2 , 3 − > 3 1->2,2->2,3->3 1>22>2,3>3
即:下标指向在数组中的数
k 1 = 2 k_1=2 k1=2时,此时需要找到如何从1-3中数中选一个数做为起点,能够快速到达一个x,使得ax=1,且这个快速到达经过的结点不能超过2+1=3个,就是所谓的只能经过k1轮。因为1-3中所有数都无法到达1个x,使得ax=1所以Takahashi不可能胜。
k 2 = 2 k_2=2 k2=2时,因为 2 − > 2 2->2 2>2,此时 a 2 = 2 a_2=2 a2=2,所以1轮就可以到 1 ≤ k 2 1\le k_2 1k2,所以Takahashi可以选2
c n t + + cnt ++ cnt++
k 3 = 3 k_3=3 k3=3时,因为 3 − > 3 3->3 3>3,此时 a 3 = 3 a_3 = 3 a3=3 ,所以1轮就可以到 1 ≤ k 3 1\le k_3 1k3,所以Takahashi可以选3
c n t + + cnt ++ cnt++
输出 c n t cnt cnt

样例2:
A = 2 , 1 A={2,1} A=2,1 1 − > 2 ; 2 − > 1 1->2 ; 2->1 1>2;2>1;
k 1 = 2 k_1= 2 k1=2时,因为 2 − > 1 2->1 2>1,且1轮符合 1 < 2 1<2 1<2所以cnt++
k 2 = 1 k_2=1 k2=1时,因为 1 − > 2 1->2 1>2,且1轮符合 1 ≤ 1 1\le 1 11,所以cnt++
输出 c n t cnt cnt.

可以看出,对于此题来说,其实就是判断有向图中环上的点,只要是在环上的点,Takahashi就一定能胜,只要不是在环上的点,Takahashi就一定胜不了。所以,计算在环上的点的个数就可以AC。

判断环的方法有很多种,这里采用拓扑排序的方法,更多请移步于判断图中存在闭环的常用方法


代码

#include 
#include 
#include 
#include 
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)

using namespace std;

typedef pair<int, int> PII;

const int N = 2e5 + 10;

int n;
int a[N];
vector<int> g[N];
int din[N];
queue<int> q;

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], g[i].psb(a[i]), din[a[i]] ++;
    
    int res = n;
    for (int i = 1; i <= n; i ++)
    	if (!din[i])
    	{
    		res --;
    		q.ps(i);
    	}
    
    while (q.size())
    {
    	int t = q.front();
    	q.pop();
    	
    	for (auto c : g[t])
    	{
    		din[c] --;
    		if (!din[c])
    		{
    			res --;
    			q.ps(c);
    		}
    	}
    }
    
    cout << res << endl;
    
    return 0;
}

你可能感兴趣的:(c++,图论,开发语言)