Codeforces Round #772(Div.2) [A~D]
連結:contest link
A.Min or Sum
題目
給定一個長度為 \(n\) 的陣列 \(a\) ,可以執行任意次如下操作:
- 任取兩個整數 \(i,j\) ,使 \(a_i=x,a_j=y\) ,\(x,y\) 需要滿足 \(x\mid y=a_i\mid a_j\)
求執行操作後陣列元素和的最小值
分析
設 \(x=a_1\mid a_2\mid\cdots\mid a_n\) ,\(x\) 在執行操作的過程中是不變的
而 \(a_1\mid a_2\mid\cdots\mid a_n\leq a_1+a_2+\cdots+a_n\) ,所以元素和的最小值為 \(x\) ,考慮如何操作才能取到最小值,對於任意 \(i\in[1,n-1]\)
程式碼
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while(t--) { int n, a, res = 0; cin >> n; for(int i = 1; i <= n; i++) { cin >> a; res = res | a; } cout << res << endl; } return 0; }
B.Avoid Local Maximums
題目
給定一個長度為 \(n\) 的陣列 \(a\) ,可以執行如下操作:
- 任取一個整數 \(i\) ,使 \(a_i=x\) ,\(x\) 滿足 \(1\leq x\leq 10^9\)
求最少的運算元,使陣列不存在區域性最大值
區域性最大值的定義是:如果 \(a_{i-1}<a_i\) 且 \(a_i>a_{i+1}\) 那麼 \(a_i\) 就是區域性最大值
分析
當我們找到一個區域性最大值 \(a_{i-1}\) 時,有 \(a_{i-2}<a_{i-1},a_{i-1}>a_i\) ,那麼我們可以修改 \(a_i\)
程式碼
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
int a[MAX_N];
int n;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--) {
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
a[n + 1] = 0;
int cnt = 0;
for(int i = 3; i <= n; i++) {
if(a[i] < a[i - 1] && a[i - 1] > a[i - 2]) {
a[i] = max(a[i - 1], a[i + 1]);
cnt++;
}
}
cout << cnt << endl;
for(int i = 1; i <= n; i++)
cout << a[i] << ' ';
cout << endl;
}
return 0;
}
C.Differential Sorting
題目
給定一個長度為 \(n\) 的陣列 \(a\) ,可以執行如下操作:
- 任取三個整數 \(x,y,z(1\leq x<y<z\leq n)\) ,使 \(a_x=a_y-a_z\)
求如何操作能使陣列變為非減序列,即 \(\forall i,a_i\leq a_{i+1}\)
不要求運算元最小
分析
考慮序列的最後三個數 \(a_n,a_{n-1},a_{n-2}\) ,由上述規則可知 \(a_{n-1}\) 和 \(a_n\) 無法更改,如果 \(a_{n-1}>a_n\) ,那麼無論怎麼操作都不可能使序列非減
如果 \(a_{n-1}\leq a_n\)
- 當 \(a_n\geq 0\) 時我們可以遵循一個簡單的策略:\(i=n-2,n-3,\cdots 1\) 時依次執行操作 \((x,y,z)=(i,i+1,n)\) ,那麼 \(a_i=a_{i+1}-a_n\leq a_{i+1}\)
- 當 \(a_n<0\) 時 \(a_{n-2}\) 只有在 \(a_{n-2}\leq a_{n-1}\) 才可保證序列非減,否則 \(a_{n-2}=a_{n-1}-a_n>a_{n-1}\) ,同理可推 \(a_{n-3},a_{n-4},\cdots a_1\) ,所以只有原序列滿足非減時才能進行 \(0\) 次操作,否則無論如何操作都不可能使序列非減
程式碼
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
long long a[MAX_N];
int n;
struct node {
int x, y, z;
} step[MAX_N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--) {
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
if(a[n - 1] > a[n]) {
cout << -1 << endl;
} else {
int cnt = 0;
bool fnd = true;
for(int i = n - 2; i >= 1; i--) {
if(a[i] > a[i + 1]) {
if(a[n] >= 0) {
a[i] = a[i + 1] - a[n];
step[++cnt] = {i, i + 1, n};
} else {
fnd = false;
break;
}
}
}
if(fnd) {
cout << cnt << endl;
for(int i = 1; i <= cnt; i++)
cout << step[i].x << ' ' << step[i].y << ' ' << step[i].z << endl;
} else {
cout << -1 << endl;
}
}
}
return 0;
}
D.Infinite Set
題目
給定一個長度為 \(n\) 的陣列 \(a\) ,每個元素互不相同,設集合 \(S\) 為包含所有滿足以下條件的整數 \(x\) :
- \(x=a_i\)
- \(x=2y+1\) 且 \(y\in S\)
- \(x=4y\) 且 \(y\in S\)
給定 \(p\) ,求 \(S\) 中小於 \(2^p\) 的元素個數
分析
參考官方題解,推理自然簡明:tutorial
程式碼
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
const int MOD = 1e9 + 7;
int n, p, ans = 0;
int a[MAX_N], f[MAX_N], cnt[MAX_N];
set<int> useful;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> p;
for(int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i++) {
int x = a[i];
bool flag = false;
while(x > 0) {
if(useful.count(x)) {
flag = true;
break;
}
if(x % 2)
x /= 2;
else if(x % 4 == 0)
x /= 4;
else
break;
}
if(!flag)
useful.insert(a[i]);
}
for(int x : useful)
cnt[__lg(x)]++;
for(int i = 0; i < p; i++) {
f[i] = cnt[i];
if(i >= 1)
f[i] = (f[i] + f[i - 1]) % MOD;
if(i >= 2)
f[i] = (f[i] + f[i - 2]) % MOD;
ans = (ans + f[i]) % MOD;
}
cout << ans << endl;
return 0;
}