Codeforces Round#728 div.1+div.2题解
Posted 欣君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round#728 div.1+div.2题解相关的知识,希望对你有一定的参考价值。
div.2 视频讲解:BV19f4y1t7En
div.1 视频讲解:BV1io4y1C7Dd
div.2-A. Pretty Permutations
题目大意
有 n n n 只猫排成一排,标记为 1 1 1 到 n n n ,第 i i i 只猫位于位置 i i i 。 他们厌倦了整天在同一个地方打转,所以他们想重新安排自己,这样猫就不会像以前一样在同一个地方了。 他们也很懒惰,所以他们想尽量减少他们移动的总距离。 帮助他们决定在重新排序后每个位置应该放什么猫。
例如,如果有 3 3 3 只猫,这是一个有效的重新排序: [ 3 , 1 , 2 ] [3,1,2] [3,1,2] 。 没有猫在原来的位置。 猫移动的总距离为 1 + 1 + 2 = 4 1+1+2=4 1+1+2=4 ,因为猫 1 1 1 向右移动一位,猫 2 2 2 向右移动一位,而猫 3 3 3 向左移动两位。
题解
贪心可得,相邻交换最优。
若
n
n
n 为偶数,则相邻奇偶位交换。
若
n
n
n 为奇数,则有三只猫轮换,剩余相邻奇偶位交换。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
int T,n,i;
scanf("%d",&T);
while(T--)
scanf("%d",&n);
if(n%2)
printf("3 1 2");
for(i=4;i<=n;i+=2)
printf(" %d %d",i+1,i);
puts("");
else
for(i=1;i<=n;i+=2)
printf("%d %d ",i+1,i);
puts("");
div.2-B. Pleasant Pairs
题目大意
给定包含 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n(2 \\leq n \\leq 2 \\cdot 10^5) n(2≤n≤2⋅105) 个不同元素的数组 a i ( 1 ≤ a i ≤ 2 ⋅ n ) a_i(1 \\leq a_i \\leq 2 \\cdot n) ai(1≤ai≤2⋅n) ,求满足以下条件的 ( i , j ) (i,j) (i,j) 对:
- i < j i < j i<j ;
- a i ∗ a j = i + j a_i*a_j=i+j ai∗aj=i+j ;
题解
对于每个
i
i
i ,暴力枚举所有
a
i
a_i
ai 的倍数然后判断即可,注意
i
≠
j
i \\neq j
i=j 。
复杂度可以用调和级数证明为
O
(
n
⋅
l
o
g
(
n
)
)
O(n \\cdot log(n))
O(n⋅log(n)) 。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
int a[MAXN];
map<int,int> mp;
int main()
int T,n,i,j,k,ans;
scanf("%d",&T);
while(T--)
mp.clear();
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
mp[a[i]]=i;
ans=0;
for(i=1;i<=n;i++)
for(k=a[i];k<=2*n;k+=a[i])
j=mp[k/a[i]];
if(j&&j^i)
ans+=(k==i+j);
printf("%d\\n",ans/2);
div.2-C/div.2-A. Great Graphs
题目大意
已知有一张包含
n
(
1
≤
n
≤
1
0
5
)
n(1 \\leq n \\leq 10^5)
n(1≤n≤105) 个节点的有向图。有向图上每条边有边权值,边权值可能为正也可能为负,不存在负环。
已知节点
1
1
1 到每个节点的最短距离
d
i
d_i
di ,求满足条件的图中,边权值总和最小为多少。
题解
边权值总和最小时,必然只有一条正边,指向最远的节点。
同时,每个节点
i
i
i 会有负边指向其他更近的节点
j
j
j ,权值为
d
j
−
d
i
(
d
j
<
d
i
)
d_j-d_i(d_j < d_i)
dj−di(dj<di) 。
实现时,对所有距离排序后用前缀和处理即可。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
ll d[MAXN],sum[MAXN];
int main()
int T,i,n;
ll mx,ans;
scanf("%d",&T);
while(T--)
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lld",&d[i]);
sort(d+1,d+n+1);
for(i=1;i<=n;i++)
sum[i]=sum[i-1]+d[i];
ans=d[n];
for(i=1;i<=n;i++)
ans+=sum[i-1]-sum[0]-(i-1)*d[i];
printf("%lld\\n",ans);
div.2-D/div.1-C. Tree Array
题目大意
给定一个包含
n
(
2
≤
n
≤
200
)
n(2 \\leq n \\leq 200)
n(2≤n≤200) 个节点的树,对树上的节点进行
1
1
1 到
n
n
n 编号。
一开始随机选择一个节点,标记为
1
1
1 。
之后每次随机选择一个与已被标记的节点相邻的未标记节点,进行标记。直到所有节点都被标记完。
设
a
i
a_i
ai 为节点
i
i
i 被标记的编号。求数列
a
i
a_i
ai 的逆序数对数量的期望。
题解
考虑一对逆序数对
(
i
,
j
)
(
i
<
j
,
a
i
>
a
j
)
(i,j)(i < j,a_i>a_j)
(i,j)(i<j,ai>aj) 出现的概率
P
i
,
j
P_i,j
Pi,j,则易得总期望为
E
=
∑
i
=
1
n
∑
j
=
i
+
1
n
P
i
,
j
E=\\sum_i=1^n\\sum_j=i+1^nP_i,j
E=i=1∑nj=i+1∑nPi,j
以下图为例,假设
i
=
A
,
j
=
B
,
A
<
B
i=A,j=B,A < B
i=A,j=B,A<B ,如果希望使得
a
A
>
a
B
a_A>a_B
aA>aB ,那么必须先访问到
B
B
B 再访问
A
A
A 。
有以下三种情况:
- 若起点在红色区域,则不可能先访问到 B B B 再访问 A A A ;
- 若起点在蓝色区域,则必然先访问到
B
B
Codeforces Round #728 (Div. 2) D. Tree Array(期望+枚举)
Codeforces Round #705 (Div. 2)
Codeforces Round #774 (Div. 2)
Codeforces Round #808 (Div. 1)(A~C)