Loading

AtCoder Beginner Contest 343




B - Adjacency Matrix

难度: ⭐

题目大意

给定一个无向图的邻接矩阵, 问每个节点都和哪些节点相练;

解题思路

没啥好说的;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353, inf = 2e18;
typedef pair<int, int> PII;
int n, m;
int p[200][200];
signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin >> p[i][j];
            if(p[i][j] == 1) cout << j << ' ';
        }
        cout << endl;
    }
	return 0;
}




C - 343

难度: ⭐⭐

题目大意

给定一个数n, 输出不大于n的回文立方数x

解题思路

n的范围是1e18, 所以可以遍历1e6然后判断立方回文即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353, inf = 2e18;
typedef pair<int, int> PII;
int n, m, res;
bool check(int u){
    int p[20];
    int idx = 0;
    while(u){
        p[++idx] = u % 10;
        u /= 10;
    }
    for(int i = 1, j = idx; i <= j; i++, j--){
        if(p[i] != p[j]) return false;
    }
    return true;
}
signed main(){
    cin >> n;
    for(int i = 1; i * i * i <= n; i++){
        int k = i * i * i;
        if(check(k)) res = k;
    }
    cout << res;
	return 0;
}




D - Diversity of Scores

难度: ⭐⭐⭐

题目大意

现在有n个人, 每人初始分数为0; 现在有m次分配, 每次都会给Ai人分配Bi分; 请问每次分配后这n个人一共有多少种分数, 0也算一种;

解题思路

用数组标记一下当前所有分数的个数即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353, inf = 2e18;
typedef pair<int, int> PII;
int n, m, res = 1;
int p[N];
map<int, int> mp;
signed main(){
    cin >> n >> m;
    mp[0] = n;
    for(int i = 1; i <= m; i++){
        int a, b;
        cin >> a >> b;
        p[a] += b;
        if(!mp[p[a]]) res++;
        mp[p[a]]++;
        mp[p[a] - b]--;
        if(!mp[p[a] - b]) res--;
        cout << res << endl;
    }
	return 0;
}




E - 7x7x7

难度: ⭐⭐⭐⭐




F - Second Largest Query

难度: ⭐⭐⭐⭐

题目大意

给定一个长度为n的数组, 现在进行m次操作, 操作分为两种, 一是把下标为a的数改成b, 而是输出区间[l, r]之间第二大数的个数;

解题思路

第一次在赛时切F题, 必须记录一下; 很明显的线段树; 节点我们可以维护区间的左右端点, 最大值以及最大值的个数, 次大值以及次大值的个数;
build函数和modify函数和普通线段树一样, query函数我们可以返回结构体类型, 方便更新和输出;
本题关键还是在于pushup函数; 更新一个区间时, 其左区间有最大值和次大值, 右区间也有最大值和次大值; 找出这四个数中的最大值作为总区间的最大值, 次大值作为总区间的次大值即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353, inf = 2e18;
typedef pair<int, int> PII;
int n, m, res = 1;
struct node{
    int l, r;
    int maxn, remaxn;
    int mnum, rnum;
}tr[4 * N];
int p[N];
void pushup(node& root, node& left, node& right){
    if(left.maxn == right.maxn){
        root.maxn = left.maxn;
        root.mnum = left.mnum + right.mnum;
        if(left.remaxn == right.remaxn){
            root.remaxn = left.remaxn;
            root.rnum = left.rnum + right.rnum;
        }
        else if(left.remaxn > right.remaxn){
            root.remaxn = left.remaxn;
            root.rnum = left.rnum;
        }
        else if(left.remaxn < right.remaxn){
            root.remaxn = right.remaxn;
            root.rnum = right.rnum;
        }
    }
    else if(left.maxn > right.maxn){
        root.maxn = left.maxn;
        root.mnum = left.mnum;
        if(left.remaxn == right.maxn){
            root.remaxn = left.remaxn;
            root.rnum = left.rnum + right.mnum;
        }
        else if(left.remaxn > right.maxn){
            root.remaxn = left.remaxn;
            root.rnum = left.rnum;
        }
        else if(left.remaxn < right.maxn){
            root.remaxn = right.maxn;
            root.rnum = right.mnum;
        }
    }
    else if(left.maxn < right.maxn){
        root.maxn = right.maxn;
        root.mnum = right.mnum;
        if(left.maxn == right.remaxn){
            root.remaxn = left.maxn;
            root.rnum = left.mnum + right.rnum;
        }
        else if(left.maxn > right.remaxn){
            root.remaxn = left.maxn;
            root.rnum = left.mnum;
        }
        else if(left.maxn < right.remaxn){
            root.remaxn = right.remaxn;
            root.rnum = right.rnum;
        }
    }
}
void build(int u, int l, int r){
    if(l == r) tr[u] = {l, r, p[l], 0, 1, 0};
    else{
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
    }
}
void modify(int u, int pos, int x){
    if(tr[u].l == tr[u].r && tr[u].l == pos){
        tr[u].maxn = x;
    }
    else{
        int mid = tr[u].l + tr[u].r >> 1;
        if(pos <= mid) modify(u << 1, pos, x);
        else modify(u << 1 | 1, pos, x);
        pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
    }
}
node query(int u, int l, int r){
    if(tr[u].l >= l && tr[u].r <= r){
        return tr[u];
    }
    else{
        int mid = tr[u].l + tr[u].r >> 1;
        node a, b;
        int f1 = 0, f2 = 0;
        if(l <= mid){
            f1++;
            a = query(u << 1, l, r);
        }
        if(r > mid){
            f2++;
            b = query(u << 1 | 1, l , r);
        }
        if(f1 && f2){
            node c = {l, r};
            pushup(c, a, b);
            return c;
        }
        else{
            if(f1) return a;
            if(f2) return b;
        }
    }
}
signed main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> p[i];
    build(1, 1, n);
    for(int i = 1; i <= m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        if(a == 1){
            modify(1, b, c);
        }
        else{
            cout << query(1, b, c).rnum << endl;
        }
    }
	return 0;
}
posted @ 2024-03-02 22:39  mostimali  阅读(167)  评论(0编辑  收藏  举报