Codeforces Round 940 (Div. 2) and CodeCraft-23
A. Stickogon
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
const int N = 3e5 , mod = 1e9+7;
void solve(){
vi cnt(101);
int n;
cin >> n;
for(int i = 1, x; i <= n ; i ++)
cin >> x, cnt[x] ++;
int res = 0;
for(int i = 1; i <= 100; i ++)
res += cnt[i] / 3;
cout << res << "\n";
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int TC;
for(cin >> TC; TC; TC --)
solve();
return 0;
}
B. A BIT of a Construction
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
const int N = 3e5 , mod = 1e9+7;
void solve(){
int n, k;
cin >> n >> k;
if(n == 1) cout << k << "\n";
else {
int x = 0;
while(x * 2 + 1 <= k) x = x * 2 + 1;
cout << x << " " << k - x;
for(int i = 1 ; i <= n - 2 ; i ++)
cout << " 0";
cout << "\n";
}
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int TC;
for(cin >> TC; TC; TC --)
solve();
return 0;
}
C. How Does the Rook Move?
首先和格子的放置方式没有关系,只需要考虑剩下多少行没有被占。
\(f[i]\)表示有\(i\)行没有被占领,则\(f[0] = f[1] = 1, f[i] = f[i-1] + 2\times C_{i-1}^{1} \times f[i-2]\)
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
const int N = 3e5 , mod = 1e9+7;
vi f(N+1);
void solve(){
int n , m;
cin >> n >> m;
for(int x, y; m; m --) {
cin >> x >> y;
n -= 1 + (x != y);
}
cout << f[n] << "\n";
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
f[0] = f[1] = 1;
for( int i = 2 ; i <= N; i ++ )
f[i] = (f[i-1] + 2 * (i-1) * f[i-2]) % mod;
int TC;
for(cin >> TC; TC; TC --)
solve();
return 0;
}
D. A BIT of an Inequality
题目的式子很容易化成\(f(x,z)\oplus a_y > f(x,z)\)。
有一个性质是,\(a_y\)的最高位的\(1\)如果是第\(h\)位,则\(f(x,z)\)第\(h\)位必须是\(0\),其他位随意,所以直接统计哪些包含\(y\)的区间满足条件,这里可以用到前缀和和后缀和实现。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
const int G = 30;
void solve(){
int n;
cin >> n;
vi a(n+1) , s(n + 1);
for(int i = 1; i <= n; i ++)
cin >> a[i], s[i] = s[i - 1] ^ a[i];
vector pre(G, vi(2));
vector suf(n + 2, vector(G, vi(2)));
for(int i = 0; i < G; i ++ )
pre[i][0] = 1;
for(int i = n; i >= 1 ; i -- ){
suf[i] = suf[i+1];
for(int j = 0; j < G; j ++)
suf[i][j][(s[i] >> j) & 1] ++;
}
i64 res = 0;
for(int i = 1, h; i <= n ; i ++){
h = log2(a[i]);
for(int l = 0; l < 2; l ++)
res += pre[h][l] * suf[i][h][l];
for(int j = 0; j < G; j ++)
pre[j][(s[i] >> j) & 1] ++;
}
cout << res << "\n";
return ;
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int TC;
for(cin >> TC; TC; TC --)
solve();
return 0;
}