首页 > 其他分享 >Codeforces Round 919 (Div. 2)

Codeforces Round 919 (Div. 2)

时间:2024-02-08 22:22:51浏览次数:32  
标签:le int ll Codeforces yy xx vector 919 Div

https://codeforces.com/contest/1920

B还行,C、E good(E据说是很典的dp但我是dp苦手),D、F1无聊,F2不会

A. Satisfying Constraints *800

有 \(n\) 个条件,每个条件形如 \(x\ge k,x\le k\) 或 \(x\neq k\),\(k\) 为整数。问满足条件的整数 \(x\) 的个数。

先处理 \(\ge,\le\),得到限制区间的交集,最后把区间中 \(\neq\) 的减去。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int n;
    cin >> n;
    int l = -1e9, r = 1e9;
    vector<int> neq;
    while (n--) {
        int t, x;
        cin >> t >> x;
        if (t == 1) l = max(l, x);
        else if (t == 2) r = min(r, x);
        else neq.push_back(x);
    }
    int ans = max(0, r - l + 1);
    for (int x : neq) ans -= x >= l && x <= r;
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);    
    int T; cin >> T; while (T--)
        sol();
}
 

B. Summation Game *1100

给定正整数数组。Alice先移除不超过 \(k\) 个数,然后Bob把不超过 \(x\) 个数取成相反数,然后游戏结束。Alice想最大化所有数的和 \(sum\),Bob想最小化 \(sum\),问 \(sum\) 最后会是多少。

Bob肯定会取前 \(x\) 大的数,为了减少损失,Alice也得移除最大的若干个数(不一定要移除 \(k\) 个)。从大到小排序数组,枚举Alice移除了几个数,前缀和算算答案即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int n, k, x;
    cin >> n >> k >> x;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sort(next(a.begin()), a.end(), greater<int>());
    for (int i = 1; i <= n; i++)
        a[i] += a[i - 1];
    
    int ans = -1e9;
    for (int i = 0; i <= k; i++) {
        int j = min(n, i + x);
        ans = max(ans, -a[j] + a[i] + a[n] - a[j]);
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);    
    int T; cin >> T; while (T--)
        sol();
}
 

C. Partitioning the Array *1600 暴露智商了,没做出来555

给定长度为 \(n\) 的数组,对 \(n\) 的每个因子 \(d\),把数组分成 \(n/d\) 个长度为 \(d\) 的连续子列,若存在 \(m\ge 2\) 使得每个连续子列在 \(\mod m\) 意义下完全相同,则答案加一。问答案是多少。

\(n\le 10^5, 1\le a_i\le n\)

转化成 \(\forall i\in[1,d]\),\(\exists m\ge 2\),使得 \(\ a_i\equiv a_{i+d}\pmod m\)

也就是 \(a_{i+d}-a_i\equiv 0\pmod m\)

也就是 \(m|(a_{i+d}-a_i)\)

\(m\) 取这些数的 \(\gcd\) 即可,也就是

\[\gcd (a_{1+d}-a_1,a_{1+2d}-a_1,a_{1+3d}-a_1,\cdots, \\a_{2+d}-a_2,a_{2+2d}-a_2,a_{2+3d}-a_2,\cdots, \\ \cdots ) \]

检查 \(\gcd\) 是否为 \(1\) 就行。\(O(\sqrt n n\log n)\),注意减法可能出现负数。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int P = 998244353;

void sol() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int &x : a) cin >> x;
    
    vector<int> divs;
    for (int i = 1; i <= n / i; i++) {
        if (n % i) continue;
        divs.push_back(i);
        if (i != n / i) divs.push_back(n / i);
    }
    
    int ans = 0;
    for (int d : divs) {
        int g = 0;
        for (int i = 0; i < d; i++)
            for (int j = i; j < n; j += d)
                g = __gcd(g, a[j] - a[i]);
        if (g != 1 && g != -1) ans++; //可能负数
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T; cin >> T; while (T--)
        sol();
}
 

D. Array Repetition *1900 模拟

开始数组为空,两种操作:在末尾添一个数、把整个数组复制 \(x\) 次到末尾。\(q\) 次询问某个位置 \(k\) 上的数是什么。

\(n,q\le 10^5, k_i\le 10^{18}\)

模拟。注意越界处理,别爆longlong。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void sol() {
    int n, q;
    cin >> n >> q;
    map<ll, ll> mp;
    ll idx = 0;
    vector<ll> pos;
    for (int i = 0, f = 0; i < n; i++) {
        ll t, x;
        cin >> t >> x;
        if (f) continue;
        if (t == 1) {
            pos.push_back(++idx);
            mp[idx] = x;
        } else {
            if (idx > (ll)1e18 / (x + 1)) {
                f = true;
                continue;
            }
            idx *= x + 1;
        }
    }

    while (q--) {
        ll k;
        cin >> k;
        ll ans = mp[k];
        while (!ans) {
            ll las = *prev(upper_bound(pos.begin(), pos.end(), k));
            k = (k - 1) % las + 1;
            ans = mp[k];
        }
        cout << ans << ' ';
    }
    
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);    
    int T; cin >> T; while (T--)
        sol();
}
 

E. Counting Binary Strings *2100 得加练dp了

定义“好串”:只有一个 \(1\) 的 \(01\) 串。

问恰有 \(n\) 个好子串且所有好子串的长度 \(\le k\) 的 \(01\) 串数量。

\(1\le k\le n\le 2500\)

形如 000100000 的子串对答案的贡献为 \((x+1)(y+1)\),其中 \(x,y\) 分别为左右两边 \(0\) 的数量。

dp。\(f(i,j)\) 表示有 \(i\) 个好子串,最后一段 \(0\) 的长度为 \(j\) 的串的数量。(\(1\) 和总串长完全不用管)

枚举最后一段 \(0\) 的数量 \(k\),则 \(f(i,j)+=f(i-(j+1)(k+1),k)\)

注意初值 \(f(0,0)=f(0,1)=\cdots=1\)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int P = 998244353;

void sol() {
    ll n, K;
    cin >> n >> K;
    vector f(n + 1, vector<ll>(K));
    fill(f[0].begin(), f[0].end(), 1);
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < K; j++) {
            for (int k = 0; j + k + 1 <= K && i - (j + 1) * (k + 1) >= 0; k++) {
                (f[i][j] += f[i - (j + 1) * (k + 1)][k]) %= P;
            }
        }
    }
    cout << accumulate(f[n].begin(), f[n].end(), 0ll) % P << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);    
    int T; cin >> T; while (T--)
        sol();
}
 

F1. Smooth Sailing (Easy Version) *2500 好想难写的简单二分答案+bfs

给定图,每个点是海底火山/岛屿/海洋。岛屿是个四连通区域且不与边界接壤,火山和海洋都能行船。

环岛路线:由非岛屿点组成,环绕所有岛屿,使岛屿与边界不能八连通

环岛路线的安全度:路线中每个点到每座火山的曼哈顿距离的最小值。

\(q\) 次询问,问从某点出发的环岛路线的安全度最大是多少。\(q\le 5\)

二分答案 \(mid\),把起点所在的安全度 \(\ge mid\) 的非岛屿四连通区域标出,看这个区域能把不能把岛屿的边界包含在内

也就是把上述区域ban掉,看边界与岛屿是否八连通即可。代码很长

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int dx[] = {0,0,1,-1,1,-1,-1,1};
const int dy[] = {1,-1,0,0,1,1,-1,-1};

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int n, m, q;
    cin >> n >> m >> q;
    vector g(n + 1, vector<char>(m + 1));
    queue<pair<int, int>> que;
    vector dis(n + 1, vector<int>(m + 1, -1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> g[i][j];
            if (g[i][j] == 'v') {
                que.push({i, j});
                dis[i][j] = 0;
            }
        }
    }
    
    while (!que.empty()) { //计算每个点到最近火山的曼哈顿距离
        auto [x, y] = que.front(); que.pop();
        for (int i = 0; i < 4; i++) {
            int xx = x + dx[i], yy = y + dy[i];
            if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
            if (dis[xx][yy] != -1) continue;
            dis[xx][yy] = dis[x][y] + 1;
            que.push({xx, yy});
        }
    }
    
    while (q--) {
        int x, y;
        cin >> x >> y;
        
        auto ok = [&](int mid) {
            if (dis[x][y] < mid) return false;
            vector f(n + 1, vector<int>(m + 1)); //f=1与(x,y)四连通,f=2与边界八连通
            f[x][y] = 1;
            queue<pair<int, int>> q;
            q.push({x, y});
            while (!q.empty()) {
                auto [x, y] = q.front(); q.pop();
                for (int i = 0; i < 4; i++) {
                    int xx = x + dx[i], yy = y + dy[i];
                    if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
                    if (f[xx][yy] || dis[xx][yy] < mid || g[xx][yy] == '#') continue;
                    f[xx][yy] = 1;
                    q.push({xx, yy});
                }
            }

            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++)
                    if ((i == 1 || i == n || j == 1 || j == m) && !f[i][j])
                        q.push({i, j}), f[i][j] = 2;
            while (!q.empty()) {
                auto [x, y] = q.front(); q.pop();
                for (int i = 0; i < 8; i++) {
                    int xx = x + dx[i], yy = y + dy[i];
                    if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
                    if (g[xx][yy] == '#') return false;
                    if (f[xx][yy]) continue;
                    f[xx][yy] = 2;
                    q.push({xx, yy});
                }
            }
            return true;
        };
        
        int l = 0, r = 2e5, ans = 0;
        while (l <= r) {
            int mid = l + r >> 1;
            if (ok(mid)) ans = mid, l = mid + 1;
            else r = mid - 1;
        }
        cout << ans << '\n';
    }
    
    return 0;
}

标签:le,int,ll,Codeforces,yy,xx,vector,919,Div
From: https://www.cnblogs.com/wushansinger/p/18012189

相关文章

  • CF1863F Divide, XOR, and Conquer 题解
    简要题意你有两个指针\(l,r\)初始时\(l=1,r=n\)。你可以操作若干次知道\(l=r\)。每次操作你可以选择一个整数\(k\in[l,r)\),记\(x=\bigoplus_{i=l}^ka_i,y=\bigoplus_{i=k+1}^ra_i\)。如果\(x\leqy\),你可以令\(l=k+1\)。如果\(x\geqy\),你可以令\(r=k\)。......
  • Codeforces Round 923 (Div. 3)赛后总结
    CodeforcesRound923(Div.3)A没什么好说的,纯秒。B一开始不知道怎么做,后面用了一个比较麻烦复杂的思路,可以做,但是开数时漏了数组0下标,导致样例一部分一直是空的。C非常简单的一道题,判断条件也比较好找,但是再提醒一遍自己,数组开大点,应该数组开小了,导致样例8没过真的气,最后......
  • Codeforces Round 260 (Div. 1)A. Boredom(dp)
    最开始写了一发贪心wa了,然后这种选和不选的组合优化问题,一般是考虑动态规划\(dp[i][0]:\)表示第i个数不选的最大值\(dp[i][1]:\)表示第i个数选的最大值考虑转移:\(dp[i][0]=max(dp[i-1][1],dp[i-1][0])\)\(dp[i][1]=dp[i-1][1]+a[i]*i\)需要将每一个数用一个桶统计次数因......
  • Codeforces Round 923 (Div. 3)
    A.MakeitWhiteA题不多说B.FollowingtheString题目一开始没看懂,后面发现数字是指字母出现的次数,读懂题目后就好做了,先把26个字母放在一个数组里全部初始化为0,然后用1次就加1,然后要根据数字来选数的话就可以遍历数组当满足就break;也可以通过集合。C.ChoosetheDifferent......
  • Codeforces Round 909 (Div. 3)
    题目链接A.若n是3的倍数,那么输出第二,因为不管先手如何操作,后手只要跟先手出的相反那么先手就永远不会赢其他情况,先手都能赢#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;voidsolve(){intn;cin>>n;if((n+1)%3==0|......
  • Codeforces-Round-917
    比赛链接A.LeastProduct假如序列中有\(0\),那么答案是\(0\)。否则如果有奇数个负数,只需要让每个数的绝对值最大:不操作是最优的。否则如果有偶数个负数,乘积只会\(\ge0\),为了达到最小值\(0\),只需要将任意一个数改成\(0\)。时间复杂度\(\mathcal{O}(n)\)。codeforA......
  • Codeforces-Pinely-Round-3
    比赛链接A.DistinctButtons扣掉一个方向就是只能走到相邻两个象限以及和这两个象限相邻的坐标轴上,判一下是不是所有的点都满足就行。判的时候只需要判是否所有\(x\le0\)(落到二、三象限),或者所有\(x\ge0\)(四、一象限),或者所有\(y\le0\)或者所有\(y\ge0\)就行,......
  • Codeforces Round 923 (Div. 3)
    CodeforcesRound923(Div.3)A-MakeitWhite分析在字符串中找到第一个B的位置l和最后一个B的位置r,打印r-l+1即可如果找不到B打印-1code#include<bits/stdc++.h>#defineintlonglong#defineyescout<<"YES"<<'\n'#defineno cout<<"NO"......
  • Codeforces Round 921 (Div. 2)
    https://codeforces.com/contest/1925恶心round,从C题开始每题都是一眼看出做法但是细节挺多的题,烦的一比。A.WeGotEverythingCovered!*800给定\(n,k\),若所有长度为\(n\)且仅由字母表中前\(k\)个小写字母组成的串都是\(s\)的子序列,则称\(s\)是"EverythingCover......
  • Codeforces Round 923 (Div. 3)(A~F)
    目录ABCDEFA#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definepllpair<longlong,longlong>#de......