cf summer vacation training 1700-1800 day1

1852B Imbalanced Arrays

  1. bi + bj must not be 0. For example, if the absolute value of bi is n, bi can only choose one between the pair of numbers n and -n.
  2. Double pointers (this is why the ascending order is sorted), it is similar to either not including r in the answer to l, or including l in the answer to r, but both cannot be satisfied at the same time, because I just started to answer the question of 1800 and I couldn't I express my meaning very clearly. Please forgive me.

1850H. The Third Letter

Idea: Just search, but using val[] to verify the results is a trick I didn't expect
:

  • To learn vector<pair<int, int>>a、vector<pair<int, int>>a[3]、vector<vector<pair<int, int>>> a、vector<array<int, 3>>athe differences between these containers, you can check the documentation for specific APIs like clear, emplace, and push_back.

I don’t know why I keep wagging, it’s obviously similar to what I wrote in the question.
Insert image description here

#include <bits/stdc++.h>
#include <vector>
#include<iostream>
#include<unordered_map>
#include <queue>
#include <set>
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
vector<pii> adj[N];
int vis[N], val[N];

void dfs(int u)
{
    
    
    vis[u] = 1;
    int sz = adj[u].size();
    for (auto x : adj[u])
    {
    
    
        int v = x.first, w = x.second;
        if (vis[v] == 0)
        {
    
    
            
            val[v]= w + val[u];

            dfs(v);
        }   
    }
}
void solve()
{
    
      
    int n, m;
    cin >> n >> m; 

    for (int i = 1; i <= n; ++ i)
    {
    
    
        adj[i].clear();
        vis[i] = 0, val[i] = 0;   
    }

    vector<array<int, 3>> c;
    for (int i = 1; i <= m; ++ i)
    {
    
    
        int a, b, d;
        cin >> a >> b >> d;
        adj[a].push_back({
    
    b, d});
        adj[b].push_back({
    
    a, -d});
        c.push_back({
    
    a, b, d});
    }

    for (int i = 1; i <= n; ++ i)
    {
    
    
         if (vis[i] == 0) dfs(i);
    }

    for (int i =1; i <= m; ++ i)
    {
    
    
        int a = c[i - 1][0], b = c[i - 1][1], d = c[i - 1][2];
        if (val[a] + d != val[b] ) 
        {
    
    
            cout << "NO" << endl;
            return ;
        }
    }

    cout << "YES" << endl;
}
int32_t main()
{
    
    
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin >> T;
    while (T --) solve();
    return 0;
}

1833G Ksyusha and Chinchilla

The meaning of the question is here

trick:

  • Learned to create a method object inside the method
  • With a deeper understanding of dfs, it turns out that idx can be passed in to indicate which edge is currently used to reach the current point, and the results can be collected directly when the conditions are met;
  • The ok global variable is used to indicate whether the subtree meets the conditions, and siz[1] determines whether the root node meets the conditions, because in dfs, sz>3 will make ok = false, but for the root node, sz != 0 does not meet the meaning of the question. of
  • Use Uniconnect Block == 3 to simplify the meaning of the question and reduce the difficulty of thinking.
#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;



void solve()
{
    
      
    int n;
    cin >> n;
    vector<vector<pii>> edges(n + 1);
    for (int i = 1; i < n; ++ i)
    {
    
    
        int u, v; cin >> u >> v;
        edges[u].push_back({
    
    v, i}), edges[v].push_back({
    
    u, i});
    }
    bool ok = true;
    vector<int> sz(n + 1);
    vector<int> ans;
    //idx指的是由哪条边找到当前点的
    function<void(int, int, int)> dfs = [&](int u, int fa, int idx) 
    {
    
    
        sz[u] = 1;
        for (auto [v, idx] : edges[u])
        {
    
    
            if (v == fa) continue;
            else
            {
    
    
                dfs(v, u, idx);
                sz[u] += sz[v];
            }
        }      
        if (sz[u] > 3)
        {
    
    
            ok = false;
            return ;
        }
        else if (sz[u] == 3)
        {
    
    
            sz[u] = 0;
            if (idx != 0) ans.push_back(idx);//u = 1的时候一条边都不需要剪
        }
    };

    dfs(1, 0, 0);

    ok &= !sz[1];//根节点所在的联通块为0才说明当前树全被剪完了
    if (ok)
    {
    
    
        cout << ans.size() << endl;
        for (auto idx : ans) cout << idx << " ";
        cout << endl;
    }
    else cout << -1 << endl;
}
int32_t main()
{
    
    
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin >> T;
    while (T --) solve();
    return 0;
}

1833F Ira and Flamenco (complete the line segment tree to see)

This question seems to require the use of line segment trees, chairman trees or something like that. The solution to the question is available in Luogu, it is very clear. . I'm going to take extra classes.

1809D Binary String Sorting

Question meaning:
Two operations turn the current string into a non-decreasing string

  1. Deleting an element costs 1e12 + 1
  2. Swap two consecutive elements at a cost of 1e12

In fact, it is a greedy question
Insert image description here

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

const long long pw10 = 1e12;

void solve()
{
    
      
    string s;
    cin >> s;
    long long ans = 1e18;
    int cnt0 = 0, cnt1 = count(s.begin(), s.end(), '1');
    //cnt0表示当前位置之前有多少0,cnt1表示当前位置之后有多少1
    int n = s.size();
    if (n == 1) ans = 0;
    for (int i = 0; i < n - 1; ++ i)
    {
    
    
        if (s[i] == '0') cnt0 ++;
        else cnt1 --;
        int k = cnt0 + cnt1 + (s[i] == '1') + (s[i + 1] == '0');
        long long cur = 0;
        cur = (n - k) * (pw10 + 1);
        if (s[i] > s[i + 1]) cur += pw10;
        ans = min(cur, ans);
    }
    cout << ans << endl;
}
int32_t main()
{
    
    
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin >> T;
    while (T --) solve();
    return 0;
}

1780D Bit Guessing Game (This question is really difficult, I can only say that I understand the answer, but I really can’t figure it out)

trick:

  • How to get the position of the last 1 of n' during the iteration process, just rely on the question to give me the number of 1's in the binary representation of n'
  • How to make the last 1 to the last 0 in binary n become 1? Let the position of the last 0 in binary n be i, n' - 2 i .

I roughly summed it up:

Insert image description here
Insert image description here

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;


int ask(int x)
{
    
    
    cout << "- " << x << endl;
    cout.flush();
    int t_cnt; cin >> t_cnt;
    return t_cnt;
}
void solve()
{
    
      
    int cnt; cin >> cnt;
    int last = 1;
    int ans = 0;
    while (cnt)
    {
    
    
        int t_cnt = ask(last);//减last的目的其实就是让n'最后一个1和第0位之间全部变成1,这样我们就知道最后1位1所在的位置了
        last = (1 << (t_cnt - cnt + 1));//t - cnt + 1获得当前n'的最后一个1和第0位的距离
        ans |= last;// |=就是+=  
        cnt -- ;
    }    

    cout << "! " << ans << endl;
}
int32_t main()
{
    
    
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin >> T;
    while (T --) solve();
    return 0;
}

Guess you like

Origin blog.csdn.net/chirou_/article/details/132062798