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++ #include #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 #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 = 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;
}
posted @ 2024-07-27 01:46  知-返  阅读(898)  评论(0编辑  收藏  举报