首页 > 其他分享 >AtCoder Beginner Contest 343

AtCoder Beginner Contest 343

时间:2024-03-02 23:45:03浏览次数:27  
标签:std AtCoder cnt Beginner idx int Info 次大值 343

基本情况

前四题秒了,但是都有不够优雅的地方

F知道是线段树,但是写不出来,极其绝望

C - 343

C - 343 (atcoder.jp)

更简洁的回文判断

MyCode

bool check_p(i64 x) {
    std::string s(std::to_string(x));
    int n = sz(s);
    for (int i = 0; i < n / 2; i++) {
        if (s[i] != s[n - i - 1]) return false;
    }
    return true;
}

signed main(){

    constexpr int N(1E6 + 10);

    std::cin >> n;
    
    i64 ans(1);

    for (i64 i = 0; i < N; i++) {
        i64 num = i * i * i;
        if (num > n) {std::cout << ans << '\n'; return 0;}
        if (check_p(num)) ans = num;
    }

    std::cout << ans << '\n';

    return 0;
}

STD

int main() {

    i64 N;
    std::cin >> N;
    
    i64 ans = 0;
    for (i64 a = 1; a * a * a <= N; a++) {
        std::string s = std::to_string(a * a * a);
        if (s == std::string(s.rbegin(), s.rend())) {//更简洁的回文判断
            ans = a * a * a;
        }
    }
    std::cout << ans << "\n";
    
    return 0;
}

D - Diversity of Scores

D - Diversity of Scores (atcoder.jp)

不知道map可以erase导致的

MyCode

signed main(){
    int N, T;
    std::cin >> N >> T;
    std::vector<i64> a(N);
    std::set<i64> S(all(a));
    std::map<i64, int> cnt;
    cnt[0] = N;
    for (int _ = 1; _ <= T; _++) {
        int idx; i64 add;
        std::cin >> idx >> add;
        idx--;
        if (cnt.count(a[idx])) {
            cnt[a[idx]]--;
            if (cnt[a[idx]] == 0) {
                S.erase(a[idx]);
            }
        }
        a[idx] += add;
        cnt[a[idx]]++;
        S.insert(a[idx]);
        std::cout << sz(S) << '\n';
    }
    return 0;
}

STD

signed main(){
    int N, T;
    std::cin >> N >> T;
    std::vector<i64> a(N);
    std::map<i64, int> cnt;
    cnt[0] = N;
    for (int _ = 1; _ <= T; _++) {
        int idx; i64 add;
        std::cin >> idx >> add;
        idx--;
        if (--cnt[a[idx]] == 0) cnt.erase(a[idx]);//直接用map执行删除操作就行
        a[idx] += add;
        cnt[a[idx]]++;
        std::cout << sz(cnt) << '\n';
    }
    return 0;
}

F - Second Largest Query

F - Second Largest Query (atcoder.jp)

线段树掌握不到位

这里只需要维护次大值,并不需要主席树

而且也不需要通过map等暴力统计次大值数量,可以优雅地直接用线段树在合并时维护

#include <bits/stdc++.h>

using i64 = long long;
template<class Info>
struct SegmentTree {
    int n;
    std::vector<Info> info;
    SegmentTree() : n(0) {}
    SegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template<class T>
    SegmentTree(std::vector<T> init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template<class T>
    void init(std::vector<T> init_) {
        n = init_.size();
        info.assign(4 << std::__lg(n), Info());
        std::function<void(int, int, int)> build = [&](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init_[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void modify(int p, int l, int r, int x, const Info &v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        if (x < m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) {
            return Info();
        }
        if (l >= x && r <= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    template<class F>
    int findFirst(int p, int l, int r, int x, int y, F pred) {
        if (l >= y || r <= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findFirst(2 * p, l, m, x, y, pred);
        if (res == -1) {
            res = findFirst(2 * p + 1, m, r, x, y, pred);
        }
        return res;
    }
    template<class F>
    int findFirst(int l, int r, F pred) {
        return findFirst(1, 0, n, l, r, pred);
    }
    template<class F>
    int findLast(int p, int l, int r, int x, int y, F pred) {
        if (l >= y || r <= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findLast(2 * p + 1, m, r, x, y, pred);
        if (res == -1) {
            res = findLast(2 * p, l, m, x, y, pred);
        }
        return res;
    }
    template<class F>
    int findLast(int l, int r, F pred) {
        return findLast(1, 0, n, l, r, pred);
    }
};

struct Info {
    //最大值,最大值个数,次大值,次大值个数
    int mx1 = -1;
    int cnt1 = 0;
    int mx2 = -2;
    int cnt2 = 0;
};

Info operator+(Info a, Info b) {
    //区间合并维护次大值和次大值个数
    if (a.mx1 == b.mx1) {//如果两个区间最大值相等
        if (a.mx2 < b.mx2) {//维护次大值
            std::swap(a, b);
        }
        a.cnt1 += b.cnt1;//维护最大值个数
        if (a.mx2 == b.mx2) {//如果两者次大值相等
            a.cnt2 += b.cnt2;//相加次大值
        }
        return a;
    }
    //如果两个区间最大值不等
    if (a.mx1 < b.mx1) {//先把情况变成a最大值最大
        std::swap(a, b);
    }
    if (b.mx1 > a.mx2) {//如果b的最大值比a的次大值大(此时a的最大值肯定是最大的,所以b的最大值就是次大值)
        a.mx2 = b.mx1;//维护次大值
        a.cnt2 = b.cnt1;//显然次大值改变了,所以个数改成b的最大值的个数
    } else if (b.mx1 == a.mx2) {//两个一样,就相加
        a.cnt2 += b.cnt1;
    }
    return a;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int N, Q;
    std::cin >> N >> Q;
    
    std::vector<int> A(N);
    for (int i = 0; i < N; i++) {
        std::cin >> A[i];
    }
    
    SegmentTree<Info> seg(N);
    for (int i = 0; i < N; i++) {
        seg.modify(i, Info{A[i], 1, -1, 0});
        //单点修改,最大值等于自己,个数为1.没有次大值,所以设成{0, 1}
    }
    
    while (Q--) {
        int o;
        std::cin >> o;
        
        if (o == 1) {
            int p, x;
            std::cin >> p >> x;
            p--;
            seg.modify(p, {x, 1, -1, 0});
        } else {
            int l, r;
            std::cin >> l >> r;
            l--;
            std::cout << seg.rangeQuery(l, r).cnt2 << "\n";
        }
    }
    
    return 0;
}

标签:std,AtCoder,cnt,Beginner,idx,int,Info,次大值,343
From: https://www.cnblogs.com/kdlyh/p/18049472

相关文章

  • C - 343
    C-343https://atcoder.jp/contests/abc343/tasks/abc343_c 思路先找出最大三次方数,次数小于或者等于n,参考:在三次方根的可能范围内,使用二分查找法,定位最大的三次方根https://www.cnblogs.com/Ghost-Knight/p/17970849 从此最大的三次方根开始,向下枚举,枚举过程中对......
  • ABC343
    T1:WrongAnswer模拟代码实现a,b=map(int,input().split())c=a+bifc==0:print(1)else:print(0)T2:AdjacencyMatrix模拟代码实现n=int(input())a=[list(map(int,input().split()))foriinrange(n)]foriinrange(n):print(*[j+1f......
  • AtCoder Beginner Contest 343:起航
    AtCoderBeginnerContest343:起航2024/3/2/22:53有点儿晚了,简单总结一下。前4题都很基础,一点点小思维,其中C题边界又盲目追求刚刚好,WA了一次,总结经验,程序实际设计应该略微大于数据范围。EFG开始就做不动了,只剩了20多分钟,先通读然后看E题,E题读了半天发现大概是体积交并反......
  • AtCoder Beginner Contest 343
    B-AdjacencyMatrix难度:⭐题目大意给定一个无向图的邻接矩阵,问每个节点都和哪些节点相练;解题思路没啥好说的;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defineendl'\n'......
  • AtCoder Beginner Contest 343(小白来了)
    A-WrongAnswer思路:给你两个数(A,B0~9)输出非A+B(0~9)解法:许多(A+B)^1等等Code:#include<iostream>usingnamespacestd;intmain(){intA,B;cin>>A>>B;cout<<!(A+B);return0;}B-AdjacencyMatrix思路......
  • AtCoder Beginner Contest 342
    B-Whichisahead?难度:⭐题目大意给定n个人的位置顺序,现有m次询问,给出a,b两个人,问谁在前面;解题思路模拟就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defineendl......
  • AtCoder DP Contest vp 记录
    题单。A从\(i-1\)与\(i-2\)转移即可。#include<bits/stdc++.h>usingnamespacestd;intn;inth[100031];intdp[100031];intmain(){ cin>>n; for(inti=1;i<=n;i++)cin>>h[i]; memset(dp,0x3f,sizeof(dp)); dp[1]=0; for(inti=1;i<......
  • p3435-solution
    P3435Solutionlink画个图:显然四个黄色部分是相等的。也就是说,黄色部分是A的一个border。根据题目,周期的长度也就是Q的长度,也就是A的长度减去它的某个border的长度。现在要求这个最大,由于A的长度固定,要求的也就是A的最小border长度。根据KMP求出来的nxt......
  • AtCoder Regular Contest 172
    Preface开学了小溜一下之前没打的ARC,结果这场后面没有计数改成数论了又给我创飞了这场的DE都太玄学了,属于是自己想半天一点屌思路没有然后看一眼题解就顿悟的类型总结就是菜得发昏A-Chocolate挺有意思的签到题考虑从大到小依次切,对于一个原来\(H'\timesW'\)的块,为了尽量......
  • AtCoder Beginner Contest 342
    AtCoderBeginnerContest342比赛链接开学了,以后codeforces大概率只能补题了,但是atcoder还是可以做的A-Yay!思路找出只出现一次的字符就可以Code#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongvoidsolve(){ strings; cin>>s; std::map<ch......