首页 > 其他分享 >Codeforces Round #771 (Div. 2) A-E

Codeforces Round #771 (Div. 2) A-E

时间:2023-07-11 20:22:46浏览次数:48  
标签:连通 771 int auto Codeforces yy xx using Div

A

代码

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

int p[507];
bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> p[i];
    int pos1 = 0, pos2 = 0;
    for (int i = 1;i <= n;i++) {
        if (p[i] != i) {
            pos1 = i;
            break;
        }
    }
    for (int i = pos1 + 1;i <= n;i++) {
        if (pos1 == p[i]) {
            pos2 = i;
            break;
        }
    }
    reverse(p + pos1, p + pos2 + 1);
    for (int i = 1;i <= n;i++) cout << p[i] << " \n"[i == n];
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

B

代码

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

int a[100007];
bool solve() {
    int n;
    cin >> n;
    int mx0 = 0, mx1 = 0;
    for (int i = 1;i <= n;i++) cin >> a[i];
    for (int i = 1;i <= n;i++) {
        if (a[i] & 1) {
            if (a[i] < mx1) return false;
            mx1 = a[i];
        }
        else {
            if (a[i] < mx0) return false;
            mx0 = a[i];
        }
    }
    cout << "YES" << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << "NO" << '\n';
    }
    return 0;
}

C

题意

给定一个长为 \(n\) 的排列,将数字看作点,其中的逆序对当作一条边,问这个图有多少个连通块。

题解

知识点:贪心,单调栈。

从左到右遍历,考虑用一个单调递增栈保存之前连通块,用连通块最大数字代表它所在连通块。

之后每加入一个数字,需要和栈顶连通块比较。若小于连通块最大数字,则连通块可以与这个数字连通。随后将这个连通块弹出栈顶,继续比较下一个。

直到没有比这个数字更大的连通块,即不存在逆序对,就将之前与这个数字连通的连通块中取最大值放入栈中,表示这一整个连通块。

若不存在连通块能和这个数字连通,那么就将这个数字放入栈中。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

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

int p[100007];
bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> p[i];
    vector<int> v;
    for (int i = 1;i <= n;i++) {
        int mx = 0;
        while (v.size() && v.back() > p[i]) {
            mx = max(mx, v.back());
            v.pop_back();
        }
        v.push_back(mx ? mx : p[i]);
    }
    cout << v.size() << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}

D

题意

有一个 \(n\times m\) 的空白矩阵和一个目标矩阵,可以用一个 \(2\times 2\) 的刷子对其染色(覆盖原来的颜色)。

问能否在若干次染色后,使得空白矩阵变成目标矩阵,并给出染色方案。

题解

知识点:BFS,贪心,构造。

考虑逆推。

我们用每个 \(2 \times 2\) 的区域的左上角坐标,代表这个区域。

一开始,确定若干个 \(2 \times 2\) 的纯色区域,这些一定是可以最后一步染色的。将这些区域规定为最后一步后,这些区域之前是什么颜色并不重要,因为最后总会被覆盖的,因此这些区域的格子可以是任意颜色,作为一个通配符存在。随后,以这些区域为起点,继续往外染色即可。

按照这个规律,问题等价于在一个 \((n-1) \times (m-1)\) 地图上完成遍历连通块的问题。若整张图都被遍历了,那么染色方案是存在,方案倒序即是答案,否则无解。

时间复杂度 \(O(nm)\)

空间复杂度 \(O(nm)\)

代码

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

int n, m;
int dt[1007][1007];

int check(int x, int y) {
    int color = 0;
    for (auto xx : { x,x + 1 }) {
        for (auto yy : { y,y + 1 }) {
            if (!dt[xx][yy]) continue;
            if (!color) color = dt[xx][yy];
            if (color != dt[xx][yy]) return -1;
        }
    }
    return color;
}

void deal(int x, int y) {
    for (auto xx : { x,x + 1 })
        for (auto yy : { y,y + 1 })
            dt[xx][yy] = 0;
}

struct node {
    int x, y, c;
};

queue<node> q;
bool vis[1007][1007];
vector<node> ans;
void bfs() {
    for (int i = 1;i < n;i++)
        for (int j = 1;j < m;j++)
            if (check(i, j) != -1) q.push({ i,j,check(i,j) });
    while (q.size()) {
        auto [x, y, c] = q.front();
        q.pop();
        if (vis[x][y]) continue;
        vis[x][y] = 1;
        deal(x, y);
        if (c) ans.push_back({ x,y,c });
        for (auto xx : { x - 1,x,x + 1 }) {
            for (auto yy : { y - 1,y,y + 1 }) {
                if (xx < 1 || xx >= n || yy < 1 || yy >= m || vis[xx][yy] || check(xx, yy) == -1) continue;
                q.push({ xx,yy,check(xx,yy) });
            }
        }
    }
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1;i <= n;i++)
        for (int j = 1;j <= m;j++)
            cin >> dt[i][j];

    bfs();
    bool ok = 1;
    for (int i = 1;i < n;i++)
        for (int j = 1;j < m;j++)
            ok &= vis[i][j];
    if (ok) {
        reverse(ans.begin(), ans.end());
        cout << ans.size() << '\n';
        for (auto [x, y, c] : ans) cout << x << ' ' << y << ' ' << c << '\n';
    }
    else cout << -1 << '\n';
    return 0;
}

E

题意

给定一个长为 \(n\) 的整数数组 \(a\) ,其中每个数字都有一个颜色。

初始时,所有数字都为 \(0\) ,颜色都为 \(1\) 。

现在完成 \(q\) 个操作,有如下种类:

  1. 将 \([l,r]\) 的数字染色成 \(c\) 。
  2. 给所有颜色为 \(c\) 的数字加上 \(x\)。
  3. 输出 \(a_i\) 。

题解

知识点:珂朵莉树,树状数组,枚举。

我们先考虑操作1都是单点操作的情景。

对于操作2,因为是对所有颜色 \(c\) 的数字加,所以我们没必要枚举每个满足条件的数字,考虑用 \(col_c\) 记录当前对颜色 \(c\) 加了多少,之后遇到操作3询问的数字颜色为 \(c\) 时,输出 \(a_i + col_c\) 即可。

对于操作1,若原来的颜色是 \(c\) ,新的颜色是 \(c'\) ,我们只需要将 \(a_i\) 改为 \(a_i + col_c - col_{c'}\) ,即等价替换了颜色。

对于原题区间操作的操作1,考虑用珂朵莉树维护颜色段一致的区间,随后暴力修改每个相同颜色段区间的数字,用树状数组维护区间修改即可。

虽然这题并没有保证数据随机,但考虑势能分析区间数。每次操作最多新增 \(2\) 段区间,而一次区间减少段数最多为区间新增的段数,因此区间数的变化量绝对值的总和是 \(O(q)\) 的,因此区间修改的复杂度是 \(O(q \log n)\) 的。

时间复杂度 \(O(n + q\log n)\)

空间复杂度 \(O(n)\)

代码

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

template<class T>
class ODT {
    map<int, T> tree;

public:
    ODT(int n = 0, T val = T()) { init(n, val); }
    ODT(const vector<T> &src) { init(src); }

    void init(int n, T val) {
        tree.clear();
        tree[1] = val;
        tree[n + 1] = T();
    }
    void init(const vector<T> &src) {
        int n = src.size() - 1;
        init(n);
        for (int i = 1;i <= n;i++) tree[i] = src[i];
    }

    auto split(int x) {
        auto it = prev(tree.upper_bound(x));
        return tree.insert({ x,it->second }).first;
    }

    void assign(int l, int r, T val) {
        auto L = split(l), R = split(r + 1);
        tree.erase(L, R);
        tree[l] = val;
    }
};

template <class T>
class Fenwick {
    int n;
    vector<T> node;

public:
    Fenwick(int _n = 0) { init(_n); }

    void init(int _n) {
        n = _n;
        node.assign(n + 1, T());
    }

    void update(int x, T val) { for (int i = x;i <= n;i += i & -i) node[i] += val; }

    T query(int x) {
        T ans = T();
        for (int i = x;i >= 1;i -= i & -i) ans += node[i];
        return ans;
    }
    T query(int l, int r) {
        T ans = T();
        ans += query(r);
        ans -= query(l - 1);
        return ans;
    }

    int lower_bound(T val) {
        int pos = 0;
        for (int i = 1 << __lg(n); i; i >>= 1) {
            if (pos + i <= n && node[pos + i] < val) {
                pos += i;
                val -= node[pos];
            }
        }
        return pos + 1;
    }
    int upper_bound(T val) {
        int pos = 0;
        for (int i = 1 << __lg(n); i; i >>= 1) {
            if (pos + i <= n && node[pos + i] <= val) {
                pos += i;
                val -= node[pos];
            }
        }
        return pos + 1;
    }
};

ll col[1000007];
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, q;
    cin >> n >> q;

    ODT<int> odt(n, 1);
    Fenwick<ll> fw(n);

    auto color = [&](int l, int r, int c) {
        auto L = odt.split(l), R = odt.split(r + 1);
        for (auto it = L;it != R;it++) {
            fw.update(it->first, col[it->second] - col[c]);
            fw.update(next(it)->first, -col[it->second] + col[c]);
        }
        odt.assign(l, r, c);
    };

    while (q--) {
        string op;
        cin >> op;
        if (op == "Color") {
            int l, r, c;
            cin >> l >> r >> c;
            color(l, r, c);
        }
        else if (op == "Add") {
            int c, x;
            cin >> c >> x;
            col[c] += x;
        }
        else {
            int x;
            cin >> x;
            cout << fw.query(1, x) + col[odt.split(x)->second] << '\n';
        }
    }
    return 0;
}

标签:连通,771,int,auto,Codeforces,yy,xx,using,Div
From: https://www.cnblogs.com/BlankYang/p/17545806.html

相关文章

  • CodeForces 1525F Goblins And Gnomes
    洛谷传送门CF传送门套路地,将DAG的最小不交路径覆盖转化为点数减去拆点以后最大匹配。感性理解就是一开始每个点都是一条路径,一个匹配意味着两条路径结合了。由题意知,第\(i\)次进攻时最小不交路径覆盖必须\(>i\),也就是说,设最大匹配为\(k\),那么\(n-k>i\),即\(k\le......
  • E. Two Chess Pieces -- (codeforces) 树形DP
    原题链接:https://codeforces.com/contest/1774/problem/E题意:两颗棋子,给出两颗棋子必须要去的顶点,且给出两颗棋子的相隔距离不能大于d,算出两颗棋子完成目标后走的距离。最后两颗棋子都要回到顶点1上。思路:刚开始没想出来,顺着官方题解写的,大意就是我用数组s1和s2代表两颗棋子......
  • JQuery 控制 Div 显示和隐藏
    页面上有两个Div用JQuery控制Div显示和隐藏。实现Div间切换的需求<divclass="IndConKHuansoverH"id="divExtTelList">11111111111111111111<div><divclass="IndConBflex"id="divExtTelStatus">22222222222222......
  • div小窗的拖动
    最近要做一个置顶聊天框的功能,想着要给他做成可以拖动的一开始使用的是@mousedown+@mousemove+@mouseup来进行小窗口的拖动,但是出现拖动的时候小窗会闪烁,并且位置距离也不好把控,效果不好。然后借鉴了网上大神的帖子,使用v-drage和directives对div进行拖动首先,在控件最外面的div......
  • CodeForces 1508C Complete the MST
    洛谷传送门AtCoder传送门比较需要观察的题。设\(v\)为所有边权异或和。直觉是设一条未确定权值的边边权为\(v\),其他的为\(0\)最优。证明大概就是讨论MST是否全部使用未确定权值的边。若全使用了,那么根据\(\oplusw\le\sumw\)可知\(\min\sumw=\oplusw\),并且......
  • 从零开始的知识图谱生活,构建一个百科知识图谱,完成基于Deepdive的知识抽取、基于ES的简
    从零开始的知识图谱生活,构建一个百科知识图谱,完成基于Deepdive的知识抽取、基于ES的简单语义搜索、基于REfO的简单KBQA个人入门知识图谱过程中的学习笔记,算是半教程类的,指引初学者对知识图谱的各个任务有一个初步的认识。目前暂无新增计划。1.简介目标是包含百度百科、互动百......
  • CodeForces 997C Sky Full of Stars
    洛谷传送门CF传送门考虑容斥,钦定\(i\)行\(j\)列放同一种颜色,其余任意。\(i=0\)或\(j=0\)的情况平凡,下面只考虑\(i,j\ne0\)的情况。答案为:\[\sum\limits_{i=1}^n\sum\limits_{j=1}^n(-1)^{i+j+1}\binom{n}{i}\binom{n}{j}3^{(n-i)(n-j)+1}......
  • CF771C
    提供一个不需要换根的树形\(\text{dp}\)做法。假如只有一次询问,那么答案为树上两点间距离除以\(k\)向上取整,那么很自然地想到能否直接求树上所有路径长度和,然后除以\(k\)向上取整?显然是不行的,因为每条路径长除以\(k\)的余数合并后可能错误地减少贡献。于是我们考虑将路径......
  • Codeforces Round 883 (Div. 3)
    CodeforcesRound883(Div.3)A.RudolphandCuttheRope:题意:有一个糖果由n个绳子悬挂,告诉每一个绳子位于的高度和宽度,问至少间断几根才可以让candy回到groud。思路:统计有几个宽度小于高度的绳子即可voidsolve(){intn;intnum=0;cin>>n;for(inti=1;i......
  • CF div3 883
    题目链接E2按值域分治的技巧前置:\(f(k,n)=1+k+k^2+...+k^n\)\(①\):假设答案最终的\(n=2\),对于\(1+k+k^2\),我们在\([2,10^9]\)的范围二分\(k\)即可\(②\):假设答案最终的\(n>2\),那么形式至少是\(1+k+k^2+k^3......