Codeforces Round #764 (Div. 3)

Posted kaka0010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #764 (Div. 3)相关的知识,希望对你有一定的参考价值。

A - Plus One on the Subset

最大最小值之差

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5 + 10;

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        int n; cin >> n;
        vector<int> a(n+1);
        int ma = 0, mi =1e9;
        for (int i = 1; i <= n; i++) 
            cin >> a[i];
            ma = max(ma, a[i]);
            mi = min(mi, a[i]);
        
        cout << ma - mi << endl;
    

B - Make AP

要求a、b、c为等差数列,因为只改动一个数,因此固定两个数即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5 + 10;

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        ll a, b, c; cin >> a >> b >> c;
        ll d = b - a;
        if ((b + d) % c == 0 && (b+d > 0)) 
            cout << "YES" << endl;
            continue;
        
        d = c - b;
        if ((b-d)%a==0 && (b-d > 0)) 
            cout << "YES" << endl;
            continue;
        
        d = c - a;
        if (d % 2 != 0) 
            cout << "NO" << endl;
         else 
            if ((c-d/2)%b==0 && (c-d/2 > 0)) 
                cout << "YES" << endl;
             else 
                cout << "NO" << endl;
            
        
    

C - Division by Two and Permutation

数据范围很小,直接上二分图最大匹配

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5 + 10;
vector<int> g[55];
int vis[55];
int match[55];
bool dfs(int x) 
    for (auto v : g[x]) 
        if (!vis[v]) 
            vis[v] = 1;
            if (!match[v] || dfs(match[v])) 
                match[v] = x;
                return true;
            
        
    
    return false;

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        int n; cin >> n;
        for (int i = 1; i <= n; i++) g[i].clear();
        vector<int> a(n+1);
        memset(match, 0, sizeof match);
        memset(vis, 0, sizeof vis);
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= n; i++) 
            int now = a[i];
            while (now) 
                if (now <= n) g[i].push_back(now);
                now /= 2;
            
        
        int num = 0;
        for (int i = 1; i <= n; i++) 
            memset(vis, 0, sizeof vis);
            if (dfs(i)) 
                num++;
            
        
//        cout << num << endl;
        if (num == n) cout << "YES" << endl;
        else cout << "NO" << endl;
    

D - Palindromes Coloring

主要思想就是先放两两相同的,因为求的是最小值,因此最后一层如果两两没铺满就先不放了,全部转化为1去放

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5 + 10;

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        int n, k; cin >> n >> k;
        string s; cin >> s;
        vector<int> cnt(26);
        for (int i = 0; i < s.size(); i++) 
            cnt[s[i]-'a']++;
        
        vector<int> odd, even;
        int num = 0;
        int idx = 1;
        vector<int> len(n+1);
        for (int i = 0; i < 26; i++) 
//            cout << cnt[i] << endl;
            while (cnt[i] > 1) 
                cnt[i] -= 2;
                len[idx] += 2;
                idx++;
                if (idx == k + 1) 
                    idx = 1;
                
            
        
        int ans = 0, ma = 0;
        for (int i = 1; i <= k; i++) 
            ma = max(ma, len[i]);
        
        for (int i = 1; i <= k; i++) 
            if (len[i] == ma) 
                ans++;
            
        
        if (ans != k) 
            for (int i = 1; i <= k; i++) 
                if (len[i] == ma) 
                    num += 2;
                    len[i] -= 2;
                
            
        
        for (int i = 0; i < 26; i++) 
            if (cnt[i]) num++;
        

        for (int i = 1; i <= k; i++) 
            if (num) 
                len[i]++;
                num--;
            
        
        int mi = 1e9;
        for (int i = 1; i <= k; i++) 
            mi = min(mi, len[i]);
        
        cout << max(mi, 1) << endl;
    

E - Masha-forgetful

很容易想到,将全部块分为长度2和3的,因为2和3可以组成大于1的所有自然数。接下来就用简单的dp存一下,最后路径返回记录一下答案就可以了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 1e5 + 10;

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        int n, m; cin >> n >> m;
        map<string, tuple<int, int, int>> mp;
        for (int i = 1; i <= n; i++) 
            string s; cin >> s;
            for (int j = 0; j < m; j++) 
                if (j + 2 <= m) mp.insert(s.substr(j, 2), j + 1, j + 2, i);
                if (j + 3 <= m) mp.insert(s.substr(j,3), j+1, j+3, i);
            
        
        vector<int> dp(m+1);
        dp[0] = 1;
        string s; cin >> s; s = '#' + s;
        for (int i = 1; i <= m; i++) 
            if (i >= 2) 
                string tmp = s.substr(i - 1, 2);
                if (mp.count(tmp)) dp[i] |= dp[i-2];
            
            if (i >= 3) 
                string tmp = s.substr(i-2, 3);
                if (mp.count(tmp)) dp[i] |= dp[i-3];
            
        
        if (!dp[m]) cout << -1 << endl;
        else 
            int now = m;
            vector<tuple<int,int,int>> ve;
            while (now) 
                if (dp[now-2]) 
                    string tmp = s.substr(now-1, 2);
                    ve.push_back(mp[tmp]);
                    now -= 2;
                 else if (dp[now-3]) 
                    string tmp = s.substr(now-2, 3);
                    ve.push_back(mp[tmp]);
                    now -= 3;
                
            
            reverse(ve.begin(), ve.end());
            cout << ve.size() << endl;
            for (auto [l,r,i] : ve) 
                cout << l << ' ' << r << ' ' << i << endl;
            
        
    


G - MinOr Tree

求或的最小生成树

最开始我们将30位全部置为1,代表全部的边都可取

不难想到通过位去计算,从高位到低位去置0,如果当前边权包含在当前状态里,这条边是可取的,我们只需要判断连通性就好了,复杂度是 O ( 30 ∗ m ∗ l o g n ) O(30*m*logn) O(30mlogn)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5 + 10;
struct Edge 
    int u, v, w;
e[N<<1];
int fa[N];
int find(int x) return x == fa[x] ? x : fa[x] = find(fa[x]);

int main() 
    ios::sync_with_stdio(0);
    int _; cin >> _; while (_--) 
        int n, m; cin >> n >> m;
        for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v >> e[i].w;
//        for (int i = 1; i <= n; i++) fa[i] = i;
        int now = (1 << 30) - 1;
        for (int i = 29; i >= 0; i--) 
            int tmp = now - (1 << i);
            for (int j = 1; j <= n; j++) fa[j] = j;
            for (int j = 1; j <= m; j++) 
                if ((e[j].w & tmp) == e[j].w) 
                    int u = find(e[j].u);
                    int v = find(e[j].v);
                    if (u != v) 
                        fa[u] = v;
                    
                
            
            int flag = 0;
            for (以上是关于Codeforces Round #764 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #764 (Div. 3)

Codeforces Round #764 (Div. 3) A-E题解

Codeforces Round #436 E. Fire(背包dp+输出路径)

Codeforces Round #394 (Div. 2)

Codeforces Round #395 C. Timofey and a tree

[ACM]Codeforces Round #534 (Div. 2)