Codeforces Round 962 (Div. 3) A - F
A. Legs
答案就是 $ n/4+(n - n / 4==2) $
代码
点击查看代码
#include <bits/stdc++.h>
#define FOR(i,j,k) for(int i = (j);i <= (k);i ++)
#define ROF(i,j,k) for(int i = (j);i >= (k);i --)
#define PII pair<int,int>
#define int long long
#define ULL unsigned long long
#define db double
#define x first
#define y second
#define sp(x) fixed << setprecision(x)
#define all(g) g.begin(), g.end()
#define M(x) x %= mod, x += mod, x %= mod
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define ANS cout << ans << '\n'
#define de(p) cout << #p << ' ' << p << '\n'
#define END(i, n) (i == n ? '\n' : ' ')
using namespace std;
const int N = 1e5 + 10,INF = 1e9,mod = 998244353;
int n,m,k;
void solve()
{
cin >> n;
int ans = 0;
ans += n / 4;
n %= 4;
ans += n / 2;
ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
B. Scale
简单模拟
代码
点击查看代码
```C++ #includeconst int N = 1e3 + 10,INF = 1e9,mod = 998244353;
int n,m,k;
char c[N][N];
void solve()
{
cin >> n >> m;
k = n / m;
FOR(i,1,n)FOR(j,1,n) cin >> c[i][j];
FOR(i,1,k)
{
FOR(j,1,k){
cout << c[(i - 1) * m + 1][(j - 1) * m + 1];
}
cout << '\n';
}
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
</details>
##C. Sort
每次操作可以将$a[i]$变成任意一个字符
区间$[l,r]$中的$a$和$b$进行排序之后需要相等
这个问题可以等价于$\sum_{i = 'a'}^{'z'}min(\sum_{j=l}^{r}(a[j] == i)) - \sum_{j=l}^{r}(b[j] == i))$
可以用前缀和来维护区间和
<details>
<summary>点击查看代码</summary>
```C++
#include <bits/stdc++.h>
#define FOR(i,j,k) for(int i = (j);i <= (k);i ++)
#define ROF(i,j,k) for(int i = (j);i >= (k);i --)
#define PII pair<int,int>
#define int long long
#define ULL unsigned long long
#define db double
#define x first
#define y second
#define sp(x) fixed << setprecision(x)
#define all(g) g.begin(), g.end()
#define M(x) x %= mod, x += mod, x %= mod
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define ANS cout << ans << '\n'
#define de(p) cout << #p << ' ' << p << '\n'
#define END(i, n) (i == n ? '\n' : ' ')
using namespace std;
const int N = 2e5 + 10,INF = 1e9,mod = 998244353;
int n,m,k;
int a[N][40];
int b[N][40];
void solve()
{
cin >> n >> k;
FOR(i,1,n)
{
char c;cin >> c;
FOR(j,0,26) a[i][j] = a[i - 1][j];
a[i][c - 'a'] ++;
}
FOR(i,1,n)
{
char c;cin >> c;
FOR(j,0,26) b[i][j] = b[i - 1][j];
b[i][c - 'a'] ++;
}
while(k --)
{
int l,r;cin >> l >> r;
int ans = 0;
FOR(i,0,26)
{
ans += max(0ll,b[r][i] - b[l - 1][i] - (a[r][i] - a[l - 1][i]));
}
ANS;
}
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
D. Fun
可以枚举a和b,c用二分来找最大值
剪枝条件为\(a*b>1e6 || a+b>1e6\)
点击查看代码
#include <bits/stdc++.h>
#define FOR(i,j,k) for(int i = (j);i <= (k);i ++)
#define ROF(i,j,k) for(int i = (j);i >= (k);i --)
#define PII pair<int,int>
#define int long long
#define ULL unsigned long long
#define db double
#define x first
#define y second
#define sp(x) fixed << setprecision(x)
#define all(g) g.begin(), g.end()
#define M(x) x %= mod, x += mod, x %= mod
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define ANS cout << ans << '\n'
#define de(p) cout << #p << ' ' << p << '\n'
#define END(i, n) (i == n ? '\n' : ' ')
using namespace std;
const int N = 2e5 + 10,INF = 1e9,mod = 998244353;
int n,m,k;
int x;
void solve()
{
cin >> n >> x;
int ans = 0;
FOR(a,1,x)
{
FOR(b,1,x)
{
if (a + b >= x) break;
if (a * b > n) break;
int l = 1,r = x - a - b;
while(l < r)
{
int c = l + r + 1 >> 1;
if (a * b + a * c + b * c <= n) l = c;
else r = c - 1;
}
int c = l;
if (a * b + a * c + b * c <= n) ans += c;
}
}ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
E. Decode
对于一段区间 \([l,r]\) ,如果区间内\(0\)和\(1\)的个数相等那么这个区间对会使答案加\(l*(n-r +1)\)。
问题就转移成怎么快速求出所有有效区间的位置,
这里可以维护一个当前值now,遇到\(0\)就减一,遇到 \(1\) 就加一,如果一个区间的\(1\)和\(0\)的数量相同的话,那么这个区间 \([l,r]\) 中 \(l-1\) 的当前值和 \(r\) 的当前值是相同的
可以开一个map来记录每一个i的当前值对应的左部分的和,对于位置为i对答案的贡献就是\(mp[now] * (n - i + 1)\)
点击查看代码
#include <bits/stdc++.h>
#define FOR(i,j,k) for(int i = (j);i <= (k);i ++)
#define ROF(i,j,k) for(int i = (j);i >= (k);i --)
#define PII pair<int,int>
#define int long long
#define ULL unsigned long long
#define db double
#define x first
#define y second
#define sp(x) fixed << setprecision(x)
#define all(g) g.begin(), g.end()
#define M(x) x %= mod, x += mod, x %= mod
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define ANS cout << ans << '\n'
#define de(p) cout << #p << ' ' << p << '\n'
#define END(i, n) (i == n ? '\n' : ' ')
using namespace std;
const int N = 2e5 + 10,INF = 1e9,mod = 1e9 + 7;
int n,m,k;
string s;
int c[N][2];
void solve()
{
cin >> s;n = s.size();
s = " " + s;
map<int,int> mp;
int now = 0;
int ans = 0;
int res = 0;
mp[0] = 1;
FOR(i,1,n)
{
if (s[i] == '0') now --;
else now ++;
ans += mp[now] * (n - i + 1);
M(ans);
mp[now] += i + 1;
}
ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
F. Bomb
题意:给一个长度为 \(n\) 的 \(a\) 数组和\(b\)数组,可以操作 $ k$ 次
每次操作可以任选 \(i\),将得分加上 \(a[i]\) ,将 \(a[i]\) 赋值为 \(max(0,a[i] - b[i])\)
可以二分是否可以将每个 \(a[i]\) 都变成小于 \(x\) 的值。
\(check\) 函数可以遍历 \(a\) 数组算出将每个 \(a[i]\) 都变成小于 \(x\) 的值的最少操作次数
然后和 \(k\) 比较即可算出
求出最小的不能将每个 \(a[i]\) 都变成小于 \(x\) 的值的最小x,这样就可以\(O(n)\)将 \(k\) 减小至小于等于 \(n\) 的数量,由于比 \(x\) 小值都会使操作用完,所以当前一定只剩下大小为 \(x\) 的 \(a[i]\) ,答案再加上 $k * x $ 即可
点击查看代码
#include <bits/stdc++.h>
#define FOR(i,j,k) for(int i = (j);i <= (k);i ++)
#define ROF(i,j,k) for(int i = (j);i >= (k);i --)
#define PII pair<int,int>
#define int long long
#define ULL unsigned long long
#define db double
#define x first
#define y second
#define sp(x) fixed << setprecision(x)
#define all(g) g.begin(), g.end()
#define M(x) x %= mod, x += mod, x %= mod
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define ANS cout << ans << '\n'
#define de(p) cout << #p << ' ' << p << '\n'
#define END(i, n) (i == n ? '\n' : ' ')
using namespace std;
const int N = 2e5 + 10,INF = 1e9,mod = 998244353;
int n,m,k;
int a[N],b[N];
int ans;
bool check(int x)
{
int res = 0,tk = k;
FOR(i,1,n)
{
if (a[i] <= x) continue;
int t = a[i] - x - 1;
t = (t + b[i] - 1) / b[i];
t = min(t,tk);
tk -= t;
int shou = a[i],mo = a[i] - (t - 1) * b[i];
res += (shou + mo) * t / 2;
}
ans = max(ans,res);
return tk != 0;
}
void solve()
{
cin >> n >> k;
FOR(i,1,n) cin >> a[i];
FOR(i,1,n) cin >> b[i];
int l = 0,r = 1e9;
ans = 0;
while(l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
int x = l;
int res = 0;
priority_queue<PII,vector<PII>,less<>> q;
FOR(i,1,n)
{
if (a[i] <= x) continue;
int t = a[i] - x - 1;
t = (t + b[i] - 1) / b[i];
t = min(t,k);
k -= t;
int shou = a[i],mo = a[i] - (t - 1) * b[i];
int e = max(0ll,mo - b[i]);
if (e > 0) q.push({e,b[i]});
res += (shou + mo) * t / 2;
}
while(q.size() && k)
{
auto [x,y] = q.top();q.pop();
res += x;
x = max(0ll,x - y);
if (x > 0) q.push({x,y});
k --;
}
ans = max(res,ans);
ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}