我对于OI的一些拙见
就我目前对OI的学习经历而言,我觉的OI实则就是IO(Input & Output)
输入数据与输出数据,我们所需要做的只是把输入数据加工成输出数据
如果稍微分得细一点,我觉的OI题可以分为两类:
-
关于数的题
-
关于图的题
前者输入的是单纯的数字,而后者输入的则是由节点与边构成的图
先就数说起
首先,当我们输入了这些数之后,我们应该怎么办?
或者说,我们处理这些数的思路应当从何而来?
我觉得可以由一下几点入手:
- 模拟
- 贪心
- 数论
- 暴力
- 动态规划
- 二分答案
那么,有了思路,我们该如何实现呢?
对于一道较为复杂的题,我们往往会面对以下问题:
- 超过时间限制(TLE)
- 超过空间限制(MLE)
- 爆精度(数据超过long long范围)
超过时间限制的问题一般可以采用以下方法
- 卡常
- 减枝
- 记忆化
- 贪心,数论优化
- 采用高效率的数据结构
超过空间限制的问题一般可以采用以下方法
- 离散化
- 减枝
- 滚动数组
- 空间回收
爆精度的问题一般可以采用以下方法
- 高精度
- 取模
至此,我认为对于绝大多数数的问题,通过上述途径已经可以解决了
然而,有些问题读入的数据是数,但实际考察的图论问题
这种时候就需要将问题转化为图论问题
再就图说起
关于图的问题往往会因图的种类不同而受到极大影响
首先要考虑构成图的边的种类
对于无向图:
- 边要存两边,因此要开两倍空间
- 遍历时要注意防止在两点间反复遍历
对于有向图:
- 可以tarjan
- 存在环的问题
其次要考虑图的特殊性
- 二分图
->二分图的最大匹配问题
- 有向无环图(DAG)
->拓扑排序
->通过tarjan将普通有向图转化成DAG
- 树
->最近公共祖先(lca)
->树上最短路
->树链剖分
->link cut tree(LCT,动态树)
->树上差分
->点分治
- 未构建的图
->最小生成树->prim,kruscal
->kruscal重构树