Codeforces Round #641 (Div.2)

比赛链接 / 官方题解链接

A. Orac and Factors

Solution

$n+f(n)$ 一定是偶数,所以在第一次操作后,后面的操作都是加 $2$.

Code

>folded
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
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

int T, n, k;

int main(){
for(read(T); T; T--){
read(n, k);
int i = 0;
for(i = 2; i * i <= n; i++)
if(n % i == 0)
break;
if(n % i != 0) i = n;
printf("%lld\n", 1ll * n + i + 2 * (k - 1));
}
return 0;
}

B. Orac and Models

Solution

设 $dp[i]$ 为考虑前 $i$ 个数且选了第 $i$ 个数的最大长度,转移很简单。

Code

>folded
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
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 100005;

int T, n, s[N], dp[N];

int main(){
for(read(T); T; T--){
read(n);
for(int i = 1; i <= n; i++)
read(s[i]), dp[i] = 0;
int ans = 0;
for(int i = 1; i <= n; i++){
dp[i] = 1;
for(int j = 1; j * j <= i; j++)
if(i % j == 0){
if(s[i] > s[j])
dp[i] = max(dp[i], dp[j] + 1);
if(s[i] > s[i/j])
dp[i] = max(dp[i], dp[i/j] + 1);
}
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
}
return 0;
}

C. Orac and LCM

Solution

把所有数分解质因数,对于质因子 $x$,设 $a$ 是含有 $x$ 最小次数的数,次数为 $r$($r\geq0$);$b$ 是含有 $x$ 次小次数的数,次数为 $s$($s\geq0$),即 $x^r|a,x^s|b$. 那么 $x$ 对答案的贡献为 $x^s$.

因为 $a$ 和 $b$ 的 $\mathrm{lcm}$ 含有 $x$ 的次数是 $s$,而其他数对含有 $x$ 的次数一定更大,所以最后求出的 $\gcd$ 含有 $x$ 的次数就是 $s$.

Code

>folded
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
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 100005;

int n, a, mx;
multiset<int> s[200005];
LL ans = 1;

LL fpow(LL bs, LL idx){
LL res = 1;
while(idx){
if(idx & 1) res *= bs;
bs *= bs;
idx >>= 1;
}
return res;
}

int main(){
read(n);
for(int i = 1; i <= n; i++){
read(a);
mx = max(mx, a);
for(int j = 2; j * j <= a; j++){
if(a % j == 0){
int c = 0;
while(a % j == 0){
c++;
a /= j;
}
s[j].insert(c);
}
}
if(a != 1) s[a].insert(1);
}
for(int i = 2; i <= mx; i++){
if(s[i].size() < n - 1) continue;
else if(s[i].size() == n - 1)
ans *= fpow(i, *s[i].begin());
else{
s[i].erase(s[i].begin());
ans *= fpow(i, *s[i].begin());
}
}
printf("%lld\n", ans);
return 0;
}

D. Orac and Medians

Solution

首先,如果没有 $k$ 这个数,肯定是 no

然后有一个结论:答案存在的充要条件是存在两个下标相差不超过 $2$ 的数均大于等于 $k$。手玩一下发现应该是对的。

特判一下 $n=1$.

Code

>folded
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
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 100005;

int T, n, k, a[N];

int main(){
for(read(T); T; T--){
bool ok = false;
read(n, k);
for(int i = 1; i <= n; i++){
read(a[i]);
if(a[i] == k) ok = true;
}
if(!ok){ puts("no"); continue; }
ok = false;
if(n == 1){ puts("yes"); continue; }
for(int i = 1; i <= n; i++){
if(a[i] >= k){
if(i > 1 && a[i-1] >= k){
ok = true;
break;
}
if(i > 2 && a[i-2] >= k){
ok = true;
break;
}
}
}
puts(ok ? "yes" : "no");
}
return 0;
}

E. Orac and Game of Life

Solution

如果一个位置在某时刻变色了,那么它在之后的每一秒一定都会变色(比较显然)。所以我们只需要找到每一个位置第一次变色是什么时候。

如果一个位置没有变色,说明此时它周围都是异色,那么它变色的时刻就是它周围的异色方块中最小的变色时刻+1。所以说,以第一秒就会变色的点为源跑一个 $bfs$ 即可得到所有点的第一次变色时刻。

对每一个询问,如果 $p$ 小于它的变色时刻,那么颜色还是原来的原色;否则,奇偶性判断一下颜色即可。

特判一下没有会变色的点的情况。

Code

>folded
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
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 1005;

int n, m, t, dis[N][N];
char g[N][N];
bool tag[N][N];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

inline bool valid(int x, int y){
return x >= 1 && x <= n && y >= 1 && y <= m;
}

int main(){
read(n, m, t);
for(int i = 1; i <= n; i++) scanf("%s", g[i]+1);
queue<pii> q;
bool allbad = true;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
tag[i][j] = 0;
if(i > 1 && g[i-1][j] == g[i][j]) tag[i][j] = 1;
if(i < n && g[i+1][j] == g[i][j]) tag[i][j] = 1;
if(j > 1 && g[i][j-1] == g[i][j]) tag[i][j] = 1;
if(j < m && g[i][j+1] == g[i][j]) tag[i][j] = 1;
if(tag[i][j]) q.push(mp(i, j)), allbad = false;
}
}
while(!q.empty()){
pii cur = q.front(); q.pop();
for(int i = 0; i < 4; i++){
int tx = cur.first + dx[i], ty = cur.second + dy[i];
if(valid(tx, ty) && !dis[tx][ty] && !tag[tx][ty]){
dis[tx][ty] = dis[cur.first][cur.second] + 1;
q.push(mp(tx, ty));
}
}
}
while(t--){
int i, j; LL p; read(i, j, p);
if(allbad || p < dis[i][j]) putchar(g[i][j]);
else{
if((dis[i][j] - p) % 2 == 0) putchar(g[i][j]);
else putchar(((g[i][j] - '0') ^ 1) + '0');
}
puts("");
}
return 0;
}
作者

xyfJASON

发布于

2020-05-13

更新于

2020-12-20

许可协议

评论