2026-09-18 hetao1733837 的刷题记录

致敬先辈!

不过,还有就是,明天,我的最后一个完整的 O I OI OI 赛季就正式开始了。

从 2023-05-20 开始,走过了多久呢?又还要走多久呢?或者,又还能走多久?

AT_arc151_b ARC151B A < AP

原题链接:ARC151B A < AP

分析

别急,它好像每次只关心两个位置。

所以,我不放进行一些比较好看的表示,设 d p i dp_{i} dpi 表示对于所有 j < i j < i j<i 的 j j j,都有 A j = A P j A_j=A_{P_j} Aj=APj,而在 i i i 位置上有 A i < A P i A_{i}<A_{P_i} Ai<APi,那么,每次计算大概是一个,别急,这个真的可以方便地转移吗?

难道说我建一个图,每次再添加边,拿一个并查集维护吗?

我感觉这个式子在一些方面是对的。

真的是建模😭


为啥每次都想不到正解呢?

哦,有一个 A i < A P i A_i<A_{P_i} Ai<APi 就有一个 A i > A P i A_i>A_{P_i} Ai>APi,减去相等的就行了😭

那么,我们建图,有多少个连通块,就有多少个可能的取值。

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std; 
const int N = 200005;
int n, m, p[N];
int qpow(int a, int b){
	int res = 1;
	while (b){
		if (b & 1)
			res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
int fa[N];
bool vis[N];
int find(int x){
	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
void merge(int x, int y){
	x = find(x);
	y = find(y);
	if (x == y)
		return ;
	fa[x] = y;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for (int i =1; i <= n; i++){
		fa[i] = i; 
	}
	for (int i = 1; i <= n; i++){
		cin >> p[i];
		merge(i, p[i]);
	}
	int cnt = 0;
	for (int i = 1; i <= n; i++){
		vis[find(i)] = true;
	}
	for (int i = 1; i <= n; i++){
		cnt += vis[i];
	}
	cout << (qpow(m, n) - qpow(m, cnt) + mod) % mod * qpow(2, mod - 2) % mod;
	return 0;
}

初赛日 五味杂陈

AT_arc151_c ARC151C 01 Game

原题链接:ARC151C 01 Game

分析

这场可以啊,有数数,还有博弈论!写一下这个博弈论吧。

要凑的就是 0 1 的状物,所以,双方都会这么干,然后,一旦出现什么之类的东西,那么,就有一方具有必胜策略了。

我们来细想一下......

别急,难道是看 m − 1 m-1 m−1 的奇偶性吗?

并非,所以,应该是两边是 0···0 的,Takahashi 必胜;对于两边是 0···1 的,Aoki 必胜。


咋是 Nim 博弈啊😭

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
long long n, x[N];
int m, y[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    x[0] = 0;
    x[m + 1] = n + 1;
    for (int i = 1; i <= m; i++){
        cin >> x[i] >> y[i];
    }
    long long sg = 0;
    for (int i = 0; i <= m; i++){
        long long len = x[i + 1] - x[i] - 1;
        if (i == 0 && i == m){
            sg ^= len % 2;
        } 
        else if (i == 0 || i == m){
            sg ^= len;
        } 
        else if (y[i] == y[i + 1]){
            sg ^= 1;
        }
    }
    if (sg != 0) 
        cout << "Takahashi";
    else 
        cout << "Aoki";
    return 0;
}
相关推荐
UIU11412 分钟前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
raindayinrain13 分钟前
c++设计模式
开发语言·c++·设计模式
旖旎夜光15 分钟前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
像风一样自由202024 分钟前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi
D e re k ZH30 分钟前
保序回归:从 PAVA 到可并堆的单调约束优化
c++·算法·数据挖掘·回归·kotlin
青少儿编程课堂31 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:字典树前缀树与单词检索统计
c++·python·算法·bfs·信息学竞赛
Nuanyt34 分钟前
LeetCode Hot 100 链表专题2 3 题 (Java)
java·笔记·算法·leetcode·链表
海绵宝宝转agent1 小时前
LeetCodehot100题解
java·笔记·学习·算法·leetcode·深度优先
octopus_c1 小时前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
青少儿编程课堂1 小时前
2026蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:堆排序与优先队列解析
c++·python·算法·bfs·信息学竞赛