AtCoder Beginner Contest 254 A - F
看到我们集训队的榜单挺惨淡的,就来 vp 了一把,感觉 D 如果卡了 E 也应该能做
F 看着还挺有趣的,找时间补题
更新:在看了大佬的题解之后,把 F 补了
A - Last Two Digits#
直接对 100 取模
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int main()
{
int n;
cin >> n;
printf("%02d\n", n % 100);
return 0;
}
B - Practical Computing#
杨辉三角,直接写
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[110][110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for(int k=1; k<=n; k++)
{
for(int i=1; i<=k; i++)
{
if(i == 1 || i == k) num[k][i] = 1;
else
{
num[k][i] = num[k-1][i-1] + num[k-1][i];
}
}
for(int i=1; i<=k; i++)
{
if(i != 1) cout << " ";
cout << num[k][i];
}
cout << endl;
}
return 0;
}
C - K Swap#
只有对 K 同余的才能进行相邻的交换位置
只要相邻能交换位置,就相等于可以排序了
所以就对 K 同余的数字排序,然后最后判断是不是非递减的就好
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, k;
cin >> n >> k;
for(int i=0; i<n; i++)
cin >> num[i];
for(int i=0; i<k; i++)
{
vector<int>st;
for(int j=i; j<n; j+=k)
st.push_back(num[j]);
sort(st.begin(), st.end());
int cur = 0;
for(int j=i; j<n; j+=k)
num[j] = st[cur++];
}
int f = 1;
for(int i=1; i<n && f; i++)
if(num[i] < num[i-1]) f = 0;
if(f) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
D - Together Square#
唯一分解定理 + 递推
如果从 递推到 的话,只要考虑任意的组合 的所有个数的 2 倍,再加上一个 就可以了
接下来就考虑能不能快速求出 满足条件的个数
如果一个数是平方数,则质因数分解出来的频率均为偶数,我们可以根据这个要求要计算
考虑质因数分解,如果 分解出来的质因数的频率是偶数次,则无影响,如果是奇数次,则会要求 i 的质因数分解中,该质数出现的频率为奇数
我们先算出所有 必须带有的质数的乘积,然后剩下的就是求平方数的次数了,显然有:要求小于等于 x 的平方数的个数,答案为
因为 i 的范围是 ,且 ,x 为 i 必须带有的质数乘积, 表示平方数,则其数量的计算就为
质因数分解的话,直接用欧拉筛的方式预处理所有合数的其中一个因数,然后不断往下除就是了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn], pre[maxn];
ll dp[maxn];
void init(int n)
{
pre[1] = 1;
for(int i=2; i<=n; i++)
{
if(pre[i]) continue;
for(int j=i; j<=n; j+=i)
pre[j] = i;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
init(n);
for(int i=1; i<=n; i++)
{
ll temp = 0;
if(pre[i] != i)
{
ll x = i, ans = 1;
while(pre[x] != x)
{
ll now = pre[x], way = 0;
while(pre[x] == now)
{
x /= pre[x];
way++;
}
if(way & 1)
ans *= now;
}
ans *= pre[x];
temp = sqrt((i - 1) / ans);
}
dp[i] = dp[i-1] + temp * 2 + 1;
}
cout << dp[n] << endl;
return 0;
}
E - Small d and k#
这题不知道为啥放在 E 的级别了
题目给出了限定:每个点的度最多为 3,并且提问的距离也最多为 3
所以直接 bfs 搜索,然后存一下访问的点,回退状态的时候就不用整个 vis 置为 0
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
vector<int>gra[maxn];
int vis[maxn];
int bfs(int n, int k)
{
int ans = 0;
queue<pii>q;
vector<int>v;
q.push({n, 0});
while(q.size())
{
pii now = q.front();
q.pop();
if(vis[now.first]) continue;
int u = now.first;
ans += u;
v.push_back(u);
vis[u] = 1;
if(now.second == k) continue;
for(int i=0; i<gra[u].size(); i++)
{
int nex = gra[u][i];
q.push({nex, now.second + 1});
}
}
for(int i=0; i<v.size(); i++)
vis[v[i]] = 0;
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
for(int i=0; i<m; i++)
{
int x, y;
cin >> x >> y;
gra[x].push_back(y);
gra[y].push_back(x);
}
int q;
cin >> q;
while(q--)
{
int x, k;
cin >> x >> k;
cout << bfs(x, k) << endl;
}
return 0;
}
F - Rectangle GCD#
线段树 + gcd 性质
辗转相减法:如果 和 互质,则 和 也与 和 互质
由此我们可以得到
考虑,在第 行中,从 列到 列的 值就是
通过上述性质改变后:
我们可以发现通过这种差分的 形式,可以把原本一行的 表达式中的 全部删掉(除了第一个),相同地,对于每一行,其表达式都是这样
为了再次简化,我们考虑将第一列的带有 的不加入行的计算,因此可以求每一行的第 列到第 列的
剩下的所有行的第一个,可以当做一个列来计算,与行的计算相同
因此对于一个矩阵的 ,只需要计算行、列、左上角的点的 即可
这样的行列维护可以用线段树的操作进行
如果真的上面还看不懂(没有图片确实抽象),参考大佬的题解:https://zhuanlan.zhihu.com/p/524503584
注意写 的时候要记得处理 的情况,不然模 会 RE
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[2][maxn], tr[2][maxn << 2];
int dif[2][maxn];
int gcd(int x, int y)
{
if(x > y) swap(x, y);
while(x)
{
int temp = x;
x = y % x;
y = temp;
}
return y;
}
void build(int now, int l, int r)
{
if(l == r)
{
tr[0][now] = dif[0][l];
tr[1][now] = dif[1][l];
return;
}
int mid = l + r >> 1;
build(now << 1, l, mid);
build(now << 1 | 1, mid + 1, r);
for(int i=0; i<2; i++)
tr[i][now] = gcd(tr[i][now << 1], tr[i][now << 1 | 1]);
}
int query(int now, int l, int r, int L, int R, int way)
{
if(L <= l && r <= R)
return tr[way][now];
int mid = l + r >> 1, ans = 0;
if(L <= mid) ans = query(now << 1, l, mid, L, R, way);
if(R > mid) ans = gcd(ans, query(now << 1 | 1, mid + 1, r, L, R, way));
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, q;
cin >> n >> q;
for(int i=0; i<2; i++) for(int j=1; j<=n; j++) cin >> num[i][j];
for(int i=0; i<2; i++) for(int j=1; j<=n; j++) dif[i][j] = abs(num[i][j] - num[i][j-1]);
build(1, 1, n);
while(q--)
{
int h1, h2, w1, w2;
cin >> h1 >> h2 >> w1 >> w2;
int ans = num[0][h1] + num[1][w1];
if(h1 != h2) ans = gcd(ans, query(1, 1, n, h1 + 1, h2, 0));
if(w1 != w2) ans = gcd(ans, query(1, 1, n, w1 + 1, w2, 1));
cout << ans << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)