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;
}
相关推荐
wuyk5551 小时前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
stolentime2 小时前
CSP-J2026第一轮试题(附答案解析、markdown源码)
c++·csp
Rabitebla2 小时前
【Linux系统编程】 指令(二):一条路径是怎么定位到文件的
linux·c++·笔记·学习·算法
库玛西2 小时前
数据结构与算法之美:树、森林与二叉树全解析
c语言·数据结构·笔记·考研·算法·学习方法
木井巳2 小时前
【记忆化搜索】最长递增子序列
java·算法·leetcode·深度优先·剪枝·推荐算法
东方护航数据恢复(深圳)2 小时前
本地小算力设备数据恢复经典案例实操全解_东方护航数据恢复深圳店
大数据·服务器·算法·ai·gpu算力
Omics Pro2 小时前
上海AI Lab孙思琦×高张阳:虚拟细胞代码库智能体
数据库·人工智能·算法·机器学习·自然语言处理
Y幽谷客2 小时前
图像识别入门习题整理
算法
点纭2 小时前
C 语言 第七章 常用函数(3)
c语言·开发语言·算法·oracle·c#