当前位置: 首页 > article >正文

atcoder abc372 启发式合并, dp

A delete

代码:

#include <bits.stdc++.h>

using namespace std;

int main() {
    string s;
    cin >> s;
    for(auto t: s) if(t != '.') cout << t;
}

B 3 ^ A

思路:三进制转换,可以参考二进制,先把当前可以加入的最大的3的幂次加入,这样一定可以凑出答案

代码:

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> a;
    int tmp = n;
    while(tmp) {
        int l = 0, r = 10;
        while(l < r) {
            int mid = l + r + 1 >> 1;
            if(pow(3, mid) <= tmp) l = mid;
            else r = mid - 1;
        }
        tmp -= pow(3, l);
        a.push_back(l);
    }
    cout << a.size() << endl;
    for(auto t: a) cout << t << " ";
    return 0;
}

C Count ABC Again

思路:判断当前变化的位置对结果是否会产生影响,在询问前先计算有多少ABC, 每次变换位置x前后扫描一下[x - 2, x + 2]范围内是否有ABC,变换前有让cnt --, 变换后有让cnt ++

代码:

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

int main() {
    int n, q;
    cin >> n >> q;
    vector<char> s(n + 1);
    for(int i = 1; i <= n; i ++ ) cin >> s[i];
    int cnt = 0;
    for(int i = 3; i <= n; i ++ )
        if(s[i - 2] == 'A' && s[i - 1] == 'B' && s[i] == 'C')
            cnt ++;
    
    while(q -- ) {
        int x;
        char c;
        cin >> x >> c;
        string t;
        t += s[max(1, x - 2)];
        t += s[max(1, x - 1)];
        t += s[x];
        string t1;
        t1 += s[max(1, x - 1)];
        t1 += s[x];
        t1 += s[min(n, x + 1)];
        string t2;
        t2 += s[x];
        t2 += s[min(n, x + 1)];
        t2 += s[min(n, x + 2)];
        if(t1 == "ABC" || t2 == "ABC" || t == "ABC") cnt --;
        s[x] = c;
        t = s[max(1, x - 2)];
        t += s[max(1, x - 1)];
        t += s[x];
        t1 = s[max(1, x - 1)];
        t1 += s[x];
        t1 += s[min(n, x + 1)];
        t2 = s[x];
        t2 += s[min(n, x + 1)];
        t2 += s[min(n, x + 2)];
        if(t1 == "ABC" || t2 == "ABC" || t == "ABC") cnt ++;
        cout << cnt << "\n";
    }
    return 0;
}

D buildings

思路:首先对于每个点i,我们可以很容易用单调栈求出第一个大于该点的位置j,因此点i只有在(j + 1, i)这个区间内对答案有贡献, 这里可以用差分的方式计算贡献

代码:

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

int main() {
    int n;
    cin >> n;
    vector<int> a(n + 1);
    a[0] = 0x3f3f3f3f;
    for(int i = 1; i <= n; i ++ ) cin >> a[i];
    vector<int> pos(n + 1);
    stack<int> stk;
    stk.push(0);
    for(int i = 1; i <= n; i ++ ) {
        while(a[stk.top()] <= a[i]) stk.pop();
        pos[i] = stk.top();
        stk.push(i);
    }

    vector<int> ans(n + 1);
    for(int i = 1; i <= n; i ++ ) {
        ans[pos[i]] += 1;
        ans[i] -= 1;
    }
    
    for(int i = 1; i <= n; i ++ ) {
        ans[i] += ans[i - 1];
        cout << ans[i] << " ";
    }
    return 0;
}

E K-th Largest Connected Components

思路:注意到k很小,因此在查询的时候可以直接遍历。现在考虑如何存数据。可以用并查集合并两个集合,并且在合并的时候一定要将小的集合合并到大的集合中去,因为小集合合并到大集合中,最后的集合一定大于小集合元素数量的两倍,因此合并的时间复杂度不会超过logn

代码:
 

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

const int N = 2e5 + 10;

struct node {
    int num;
    priority_queue<int> q;
    /*bool operator += (node W) const {
        while(!W.q.empty()) {
            q.push(W.q.top());
            W.q.pop();
        }
    }*/
}_size[N];
int p[N];

int find(int x) {
    if(x != p[x]) {
        p[x] = find(p[x]);
    }   
    return p[x];
}

int main() {
    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; i ++ ) {
        p[i] = i;
        _size[i].num = 1;
        _size[i].q.push(i);
    }
    while(q -- ) {
        int op;
        cin >> op;
        if(op == 1) {
            int u, v;
            cin >> u >> v;
            int pu = find(u);
            int pv = find(v);
            if(pu != pv) {
                if(_size[pu].num >= _size[pv].num){
                    while(!_size[pv].q.empty()) {
                        _size[pu].q.push(_size[pv].q.top());
                        _size[pv].q.pop();
                    }
                    _size[pu].num += _size[pv].num;
                    p[pv] = pu;
                } else {
                    while(!_size[pu].q.empty()) {
                        _size[pv].q.push(_size[pu].q.top());
                        _size[pu].q.pop();
                    }
                    _size[pv].num += _size[pu].num;
                    p[pu] = pv;
                }
            }
        } else {
            int k, v;
            cin >> v >> k;
            auto q1 = _size[find(v)].q;
            for(int i = 1; i <= k - 1 && !q1.empty(); i ++ ) {
                q1.pop();
            }
            
            if(!q1.empty()) cout << q1.top() << endl;
            else cout << -1 << endl;
        }
    }
    return 0;
}
/*
2
1
-1
4
2
-1
*/

这里留下个疑问

int k, v;
            cin >> v >> k;
            auto q1 = _size[find(v)].q;
            for(int i = 1; i <= k - 1 && !q1.empty(); i ++ ) {
                q1.pop();
            }
            
            if(!q1.empty()) cout << q1.top() << endl;
            else cout << -1 << endl;

为什么在查询时直接查询_size[p[v]]答案会出错,是路径压缩不彻底的原因吗


http://www.kler.cn/a/315719.html

相关文章:

  • ❤React-React 组件基础(类组件)
  • 在 Ubuntu 上安装 `.deb` 软件包有几种方法
  • Java 网络编程(一)—— UDP数据报套接字编程
  • 【学习】【HTML】HTML、XML、XHTML
  • 深入理解接口测试:实用指南与最佳实践5.0(二)
  • learn-F12 Performance(性能)前端性能分析(LCP,CLS,INP)
  • 感知算法引入时序模型的优势
  • Unity UGUI的核心渲染组件
  • FFmpeg中结构释放小函数
  • Python在数据科学与机器学习中的应用
  • C语言 | Leetcode C语言题解之第429题N叉树的层序遍历
  • Nginx简介;Nginx安装
  • Chainlit集成LlamaIndex实现知识库高级检索(自动合并检索)
  • VUE3学习---【一】【从零开始的VUE学习】
  • Java面试篇基础部分-Synchronized关键字详解
  • python爬虫中json和xml字符串的xPath和jsonpath过滤语法区别对比
  • 零工市场小程序:推动零工市场建设
  • 【Kubernetes】常见面试题汇总(三十)
  • 【二等奖论文】2024年华为杯研赛D题成品论文(后续会更新)
  • rust GTK4 窗口创建与 wayland Subsurface (vulkan 渲染窗口初始化 (Linux) 上篇)
  • Docker实践——天池篇
  • 极度精简 Winows11 系统镜像!Tiny11 2311下载 - 支持苹果 M 芯片 Mac 安装 (ARM 精简版)!
  • get_property --Cmakelist之中
  • 关闭小广告【JavaScript】
  • 【线程】线程的同步
  • PHP转Go很丝滑开发框架设计思路-把php优秀设计借鉴到Go框架设计里面-保留php开发习惯又能提供高软件性能