首页 > 其他分享 >Atcoder Beginner Contest 372

Atcoder Beginner Contest 372

时间:2024-09-21 22:35:14浏览次数:1  
标签:Atcoder Beginner int -- && ans using 372 size

Atcoder Beginner Contest 372

A

模拟即可。

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

using ll = long long;

void solve() {
    char ch;
    while (cin >> ch) {
        if (ch != '.') {
            cout << ch;
        }
    }
}

int main() {
    int T = 1;
    // cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}

B

三进制拆分即可。

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

using ll = long long;

int m;

void solve() {
    cin >> m;
    vector <int> v;
    while (m) {
        v.push_back(m % 3);
        m /= 3;
    }
    vector <int> ans;
    for (int i = 0; i < v.size(); i ++) {
        for (int j = 0; j < v[i]; j ++) {
            ans.push_back(i);
        }
    }
    cout << ans.size() << "\n";
    for (auto i : ans) cout << i << " ";
}

int main() {
    int T = 1;
    // cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}

C

统计每个字符的贡献,每次增减。

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

using ll = long long;
const int N = 2e5 + 5;

int n, q, ans;
string S;

void solve() {
    cin >> n >> q >> S;
    for (int i = 0; i < S.size() - 2; i ++) {
        if (S[i] == 'A' && S[i + 1] == 'B' && S[i + 2] == 'C') {
            ans ++;
        }
    }   
    while (q --) {
        int i; char ch;
        cin >> i >> ch, i --;
        if (i < S.size() - 2) {
            if (S[i] == 'A' && S[i + 1] == 'B' && S[i + 2] == 'C') {
                ans --;
            }
        }
        if (i < S.size() - 1 && i > 0) {
            if (S[i - 1] == 'A' && S[i] == 'B' && S[i + 1] == 'C') {
                ans --;
            }
        }
        if (i < S.size() && i > 1) {
            if (S[i - 2] == 'A' && S[i - 1] == 'B' && S[i] == 'C') {
                ans --;
            }
        }
        S[i] = ch;
        if (i < S.size() - 2) {
            if (S[i] == 'A' && S[i + 1] == 'B' && S[i + 2] == 'C') {
                ans ++;
            }
        }
        if (i < S.size() - 1 && i > 0) {
            if (S[i - 1] == 'A' && S[i] == 'B' && S[i + 1] == 'C') {
                ans ++;
            }
        }
        if (i < S.size() && i > 1) {
            if (S[i - 2] == 'A' && S[i - 1] == 'B' && S[i] == 'C') {
                ans ++;
            }
        }
        cout << ans << "\n";
    }
}

int main() {
    int T = 1;
    // cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}

D

单调栈模板。

从后往前扫描序列,维护单调递减栈。

当前答案即栈内元素个数。

如果当前数比栈顶大,栈顶就没有意义了,弹栈。

随后当前点入栈。

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

using ll = long long;
const int N = 2e5 + 5;

int n, a[N];
int q[N], t;

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
    }
    vector <int> ans;
    for (int i = n; i >= 1; i --) {
        ans.push_back(t);
        while (t && a[i] > a[q[t - 1]]) t --;
        q[t ++] = i;
    }
    reverse(ans.begin(), ans.end());
    for (auto i : ans) {
        cout << i << " ";
    }
}

int main() {
    int T = 1;
    // cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}

E

原题:P3224 永无乡

用并查集维护连通性,平衡树维护权值。

合并时启发式合并。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
const int N = 2e5 + 5;
__gnu_pbds::tree<int, __gnu_pbds::null_type, greater<int>,
__gnu_pbds::rb_tree_tag,
__gnu_pbds::tree_order_statistics_node_update> S[N];
int n;
int p[N], q[N], fa[N], Q;
int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
	int fx = find(x), fy = find(y);
	if (fx == fy) return ;
	if (S[fx].size() > S[fy].size()) 
		swap(fx, fy);
	for (auto num : S[fx]) 
		S[fy].insert(num);
	S[fx].clear();
	fa[fx] = fy;
}
int query(int x, int y) {
	int id = find(x);
	if (S[id].size() < y) return -1;
	return q[*S[id].find_by_order(y - 1)];
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> Q; 
	for (int i = 1; i <= n; i ++) {
		p[i] = i;
		q[p[i]] = i, fa[i] = i;
		S[i].insert(p[i]);
	}
	int op; int x, y;
	while (Q --) {
		cin >> op >> x >> y;
		if (op == 1) {
			merge(x, y);
		} else cout << query(x, y) << "\n";
	}
	return 0;
}

F

考虑把 \(2M\) 个连有附加边的点单独拎出来,称为特殊点。

把相邻特殊点之间通过普通点连接的路径缩成一条边,边权为走环的路径长度。

然后考虑动态规划。定义 \(dp_{i,j}\) 表示从 \(1\) 走到 \(i\) 用了 \(j\) 步的方案数。

\[dp_{v,j+w} \leftarrow dp_{v,j+w} + dp_{u,j} \]

这样可求出以特殊点结尾的方案数。

考虑以普通点结尾的方案数。对于每个特殊点 \(u\),只统计环上在 \(u\) 与 \(u\) 的下一个特殊点 \(v\) 间的普通点,这样可做到不重不漏。

对于普通点在 \(u,v\) 间的普通点 \(x\),答案为 \(dp_{u,k-dis(u,x)}\),

所以每个特殊点 \(u\) 对答案的贡献为:\(\sum_{i=0}^{dis(u,v)-1} dp_{u,k-i}\)。

时间复杂度:\(O(n+mk)\)。

实现时注意边界问题,边和特殊点需要去重。

为了实现方便,令 \(1\) 号点为特殊点。

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

using ll = long long;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
const ll mod = 998244353;
const int N = 2e5 + 5;
const int M = 405;

vector <pii> E[N];
vector <int> t;
set <piii> e; 
set <int> tt;
int n, m, k, id[N];
ll dp[M][N], ans;

int dis(int x, int y) {
    return (y - x + n) % n;
}

void solve() {
    cin >> n >> m >> k;
    if (m == 0) {
        cout << 1 << "\n";
        return ;
    }
    for (int i = 1; i <= m; i ++) {
        int u, v;
        cin >> u >> v;
        e.insert({u, v, 1});
        tt.insert(u);
        tt.insert(v); // 使用 set 去重
    }
    if (tt.find(1) == tt.end()) tt.insert(1);
    for (auto i : tt) t.push_back(i);
    for (int i = 0; i < t.size(); i ++) {
        e.insert({t[i], t[(i + 1) % t.size()], dis(t[i], t[(i + 1) % t.size()])});
        id[t[i]] = lower_bound(t.begin(), t.end(), t[i]) - t.begin();
        // 离散化和相邻点连边
    }
    for (auto [u, v, w] : e) { // set 去重
        E[u].push_back({v, w});
    }
    dp[id[1]][0] = 1;
    for (int j = 0; j <= k; j ++) {
        for (int i = 0; i < t.size(); i ++) {
            for (auto [v, w] : E[t[i]]) {
                if (j + w <= k) // dp 边界
                (dp[id[v]][j + w] += dp[i][j]) %= mod;
            }
        }
    }
    for (int i = 0; i < t.size(); i ++) {
        int d = dis(t[i], t[(i + 1) % t.size()]);
        for (int j = 0; j < d && j <= k; j ++) { // 边界
            (ans += dp[i][k - j]) %= mod;
        }
    }
    cout << ans << "\n";
}
signed main() {
    int T = 1;
    // cin >> T;
    while (T --) {
        solve();
    }
    return 0;
}

标签:Atcoder,Beginner,int,--,&&,ans,using,372,size
From: https://www.cnblogs.com/maniubi/p/18424628

相关文章

  • AtCoder Beginner Contest 372
    省流版A.暴力即可B.转换3进制即可C.考虑答案的组成,仅修改发生变化的部分即可D.维护答案数组\(ans_i\),考虑枚举\(j\)对哪些\(i\)有贡献,通过单调栈找到对应的区间\(i\),通过差分维护区间加法即可E.并查集维护连通块,\(set\)维护点标号大小,合并\(set\)时启发式合并,查询......
  • UNIQUE VISION Programming Contest 2024 Autumn (AtCoder Beginner Contest 372)
    总结(我的塘人局):单调栈是忘得差不多了 A-delete.题意:输出删除所有'.'的字符串思路:遍历输出不是'.'复杂度:O(n) Code:#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;usingi64=int64_t;voidsolve(){strings;cin......
  • ABC372 (D,E)
    ABC372(D,E)D一道比较简单的二分查找题目。观察到每个数能成为\(j\)的条件是独立的,因此想到统计每个数能成为它前面哪些数的\(j\)。对于每个\(ed​\),二分\(1\simed-1​\)中最后一个大于\(h[ed]​\)的数的位置\(st​\),那么\(h[ed]​\)可作为\(st\simed-1......
  • 设计资料保存:372-基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证
      一、板卡概述      基于V7的高性能PCIe信号处理板,板卡选用Xilinx 公司Virtex7系列FPGA XC7VX690T-2FFG1761C为处理芯片,板卡提供两个标准FMC插槽,适用于高性能采集、回放以及相关处理。通过连接不同的FMC子卡的方式,可实现不同形式的数据采集、回放、处理的功能模块。板......
  • [atcoder agc 004 c] AND Grid
    题目链接题目简述给定一个H×WH\timesWH×W的网格图,有些位置已经被涂色。要求构造两个相同大小的网格图......
  • ECON 3720: Introduction to Econometrics
    ECON 3720: Introduction to EconometricsProblem Set 02Fall Semester 2024Due: September 20th 2024Please submit the problem set no later than 5 PM on September 20th 2024. Submit the problem set to your TA’s mailbox in th......
  • 设计方案:372-基于7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台
    基于7VX690T的万兆光纤、双FMC扩展的综合计算平台RISCV芯片验证平台 一、板卡概述      基于V7的高性能PCIe信号处理板,板卡选用Xilinx 公司Virtex7系列FPGA 7VX690T-2FFG1761C为处理芯片,板卡提供两个标准FMC插槽,适用于高性能采集、回放以及相关处理。通过连接不同的FMC......
  • AtCoder Beginner Contest 371
    A-Jiro输入\(AB,BC,AC\)的大小关系,输出中位数。手动模拟一下。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglongintread(){intx=0;boolf=false;charc=getchar();while(c<'......
  • AtCoder Beginner Contest 371
    A-Jiro(abc371A)题目大意三个人,给定他们相互之间的大小关系。问谁在中间。解题思路排个序,大小结果就是题目给的,因为问的是中间是谁,所以写的时候并没在意是升序排还是降序排。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmai......
  • AtCoder Beginner Contest 371
    ABC371总结AtCoderBeginnerContest371一些废话想着以后换一种方式写总结,不再以那种题解形式,写起来又累又难写,只对其中部分有意思的题目写出完整的题解。就是以随笔的形式,在打完比赛后写出自己的一些感悟,每道题做的过程中的一些思路、用时和需要改进的地方,就是类似随笔之类的......