[Pinely Round 4 (Div. 1 + Div. 2)](https://codeforces.com/contest/1991)

A. Maximize the Last Element

题意

给一个长度为的数组 , (n为奇数) , 每次你可以删除数组中相邻的两个数,直到数组剩下一个数,问数组最终剩下的那个数最大为多少。

思路

可以发现, 我们最终只有可能留下奇数位的元素 ,对其取max即可。

证明: 整个数组中有undefinedfrac{n+1}{2}\frac{n-1}{2}\frac{n-1}{2}1$ 个,而偶数下标剩0个。

代码

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
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define rep(i,l,r) for(int i = l;i<=r;i++)
#define per(i,r,l) for(int i = r;i>=l;i--)
const int INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int,int> PII;
void solve(){
int n;
cin>>n;
int ans = 0;
for(int i = 1;i<=n;i+=2){
int num;cin>>num; ans = max(ans,num);
}
cout<<ans<<endl;
}
signed main(){
int T = 1;
cin>>T;
while(T--){
solve();
}
return 0;
}

B. AND Reconstruction

题意

给你一个长度为 的数组b,请你构造一个长度为n的数组a,满足 , 其中undefined&$表示按位与。

若构造不出合法的数组 ,输出-1

思路

我们既然要构造a数组,那么就考虑 受到b的哪些元素影响,可以发现 只和 有关, 并且 中为1的数位,在 中都应该是1, 所以我们让 就可以得到最终的a[i]数组, 然后我们再按顺序判断一下对于所有的是否都满足

代码

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
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define rep(i,l,r) for(int i = l;i<=r;i++)
#define per(i,r,l) for(int i = r;i>=l;i--)
const int INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int,int> PII;
void solve(){
int n;
cin>>n;
vector<int>a(n+5),b(n+5);

for(int i = 1;i<n;i++){
cin>>b[i];
}
for(int i = 1;i<=n;i++){
a[i] = b[i-1] | b[i];
}
for(int i = 1;i<n;i++){
if((a[i] & a[i+1])!= b[i]) {cout<<-1<<endl;return ;}
}
for(int i = 1;i<=n;i++){
cout<<a[i]<<" ";
}
puts("");
}
signed main(){
int T = 1;
cin>>T;
while(T--){
solve();
}
return 0;
}

C. Absolute Zero

题意

给你一个长度为n的数组a, , () 你要进行至多40次操作(无需令操作数最少), 每次操作选择一个数x, 并令所有的 变为 , 其中的 表示 的绝对值。

在进行完一些操作之后,让整个a数组全部变为0。 如果无法实现, 输出-1。

思路

首先考虑不成立的情况, 如果我们令数组中所有的元素都同时减去一个偶数,那么他们的奇偶性都会保持不变; 相反如果同时减去一个奇数,那么他们的奇偶性都会变化。 而我们最终要求所有的数都是0,即都是偶数。于是我们就可以发现,**如果数组a中同时含有奇数以及偶数,那么就无法让a全部变为0。**

接下来我们考虑如何解决这道题。最多40次使我们很容易想到按位处理。

起初所有的 都满足 , 所以我们第一次操作选择 ,便可以让所有的数都满足 ,

再接着我们第二次操作选择 , 于是所有的数都满足了

不断重复如上选择,直到最后选择了

我们不断如上选择会不断缩小a数组元素的取值范围。使得最终都变为0 。

需要特殊注意的是,此时如果a数组原本为奇数数组,那么所有的数都变为了0 。 但如果a数组是偶数数组,那么最终还要在选择一次0.

代码

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
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define rep(i,l,r) for(int i = l;i<=r;i++)
#define per(i,r,l) for(int i = r;i>=l;i--)
const int INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int,int> PII;
void solve(){
int n;
cin>>n;
vector<int> a(n+5);
rep(i,1,n){
cin>>a[i];
}
int odd=0,even=0;
//特判是否能够成立
rep(i,1,n){
if(a[i]%2) odd=1;
else even=1;
}
if(odd&&even){ // 如果同时有奇数和偶数,就不能
cout<<-1<<endl;
return ;
}
vector<int> ans;//存储答案
for(int i=29;i>=0;i--) ans.push_back(1<<i);
if(even) ans.push_back(1);
cout<<ans.size()<<endl;
for(auto p : ans){
cout<<p<<' ';
}puts("");
}
signed main(){
int T = 1;
cin>>T;
while(T--){
solve();
}
return 0;
}

D. Prime XOR Coloring

题意

给你一个无向图,图中有个节点,编号从。 如果 是一个质数 (表示u和v进行按位异或) ,那么之间有一条边相连。 请你给这个节点染色,使得不存在两个相邻的节点有相同的颜色。

思路

先给出结论,所有的节点最多只需要4种颜色。

因为节点 所以他们四个的颜色必须不同,我们为他们四个分配四种颜色。

于是当 时,我们直接打表输出。 当 时,我们令 , 这样就保证了任意两个相同颜色的节点的差一定是4的倍数,那么他们的异或就一定不是质数。也就满足了题意。。

代码

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
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define rep(i,l,r) for(int i = l;i<=r;i++)
#define per(i,r,l) for(int i = r;i>=l;i--)
const int INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int,int> PII;
void solve(){
int n;cin>>n;
if(n == 1){
cout<<"1\n1\n";return ;
}
if(n == 2){
cout<<"2\n1 2\n";return ;
}
if(n == 3){
cout<<"2\n1 2 2\n";return ;
}
if(n == 4){
cout<<"3\n1 2 2 3\n";return ;
}
if(n==5){
cout<<"3\n1 2 2 3 3\n";return ;
}
vector<int> color(n+5);
for(int i = 1;i<=4;i++){
color[i] = i;
}
for(int i = 5;i<=n;i++){
int t = i ^ 2;
if(i%2){
color[i] = 1;
if(t <= i) color[i] = 4 - color[t];
}else {
color[i] = 2;
if(t <= i) color[i] = 6 - color[t];
}
}w
cout<<"4\n";
for(int i = 1;i<=n;i++){
cout<<color[i]<<' ';
}
puts("");
}

signed main(){
int T = 1;
cin>>T;
while(T--){
solve();
}
return 0;
}