无标题
离散化 离散化点 1234567891011121314// 1. 复制一份用来查表vector<int> b = a; // 2. 排序 + 去重sort(b.begin(), b.end());b.erase(unique(b.begin(), b.end()), b.end());// 3. 直接修改原数组 afor (int i = 1; i <= n; i++) { // 这里的 +1 是为了适配树状数组下标从1开始 a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;}// 现在 a[i] 已经是 1 ~ N 的小整数了,直接用 离散化区间 区间离散化裸题 核心模型:离散化 思维误区 (Bug):记住离散化的前缀和是只用给pre[r]–,因为是把距离压缩到前面那个点 修正逻辑 (Patch):使用erase和uniqe,记得erase需要nums.end(*) 123456789101112131415161718192021222324...
基础算法
交互模板 C++ 代码: 1234567891011121314151617181920#include <cstdio>#include <iostream>int main() { for (int l = 1, r = 1000000000, mid = (l + r) >> 1, res; l <= r; mid = (l + r) >> 1) { std::cout << mid << std::endl; std::cin >> res; if (res == 0) { return 0; } else if (res == -1) { l = mid + 1; } else if (res == 1) { r = mid - 1; } else { puts("OvO, I AK IOI"...
三国杀自制武将
谋·王基
wp_题目多解
P7913 [CSP-S 2021] 廊桥分配 通用优化:前缀和优化输出答案 优先队列模拟 优先队列模拟飞机进入时贪心分配廊道 前缀和优化快速查询 离散化思想 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677struct tim{ int l, r;};void solve(){ int n, m1, m2; cin >> n >> m1 >> m2; vector<tim> gn(m1); vector<tim> gw(m2); rep(i, 0, m1 - 1) cin >> gn[i].l >> gn[i].r; rep(i, 0, m2 - 1) cin >>...
wp_数据结构
并查集 家谱 核心模型:题目要求给出一个父亲的名字,以及他的儿子们。接下来进行若干次查询,查询一个人的祖宗 思维误区 (Bug):套用dsu模板,但是模板默认有启发式合并 修正逻辑 (Patch):这道题强制要求了父亲与儿子的关系,所以删掉启发式合并,把father放在前面son放在后面(模板默认后面的往前面合并) 关键代码: DSU(并查集)里的启发式合并 在并查集中,启发式合并通常被称为 “按秩合并” (Union by Rank) 或 “按大小合并” (Union by Size)。 它的目的是 防止树退化成链,从而保证查询速度。 没有启发式合并:如果每次都固定把 YYY 接在 XXX 下面,而在极端数据下(比如 1→2,2→3,…,N−1→N1 \to 2, 2 \to 3, \dots, N-1 \to N1→2,2→3,…,N−1→N),并查集会变成一条长长的“链表”。查找一次祖先需要 O(N)O(N)O(N) 的时间。 有启发式合并:我们维护每棵树的 size(节点数)或 rank(高度)。永远把更小(或更矮)的那棵树,接到更大(或更高)的那棵树下面。 ...
wp_Trick
通过性质或者数学构造优化 通过元素代价优化 ImbalancedArray->根据乘法原理算出每个项的贡献->维护一个区间的最大值/最小值 核心模型:推式子模拟计算 思维误区 (Bug): 修正逻辑 (Patch) 要求区间最大值和最小值的差。进行简单的数学划分就能划出来->sum={min}+{max}. 对于每个数来说,计算他能影响到的区间,也就是他可以给总结果的贡献 根据乘法原理可以算出一个数字他可以贡献的价值为nums[i],他贡献的次数是他作为最大值/最小值出现在某个区间的组合种类数->ans +=(ll) (nums[i] x (i - le[i]+1) X (ri[i] - i+1));(乘法原理) 单调栈就是用来维护这种最近区间的 关键代码: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727...
wp_差分与前缀和
[toc] 差分与前缀和 差分 + 前缀和原理 用途:区间修改后求点值或最小值。 常见坑:差分数组需初始化,注意边界。 1234567891011121314151617181920212223242526struct niubi { int l, r, gap;};void solve() { int n, p; cin >> n >> p; vector<int> c(n + 1); for (int i = 1; i <= n; i++) cin >> c[i]; vector<int> hsh(5e6 + 1); for (int i = 1; i <= n; i++) hsh[i] = c[i] - c[i-1]; vector<niubi> nums(p + 1); for (int i = 1; i <= p; i++) cin >> nums[i].l >&...
wp_动态规划
动态规划入门 我该怎么看出这是一道DP 求最大/小值求方案数量求子序列 贪心做不了(有反例) 依赖前面的值,无后效性 怎么写DP 状态是谁?状态有哪些?状态必须包含所有能够影响下一阶段决策的信息 怎么转移?dp[i]是从哪里转移过来的?怎么转移代价最小/收益最大/能计算全部路径? 初始状态 DP数组怎么写 一般求什么什么就是DP数组 要不要开二维?就问自己:“如果有两个人同时走到第 iii 步,但他们之前的经历不同,这种不同会限制他们接下来的选择吗?” 能不能压缩?用滚动数组来代替二维,我们只考虑会影响结果的值。只记我们需要记的,过期的扔掉。 DP原理 数字三角形 用途:从顶到底或底到顶,求最大路径和。 常见坑:从底到顶递推可省去边界处理。 123456789101112void solve() { int n; cin >> n; int sjx[100][100]; for (int i = 0; i < n; i++) for (int j = 0; j <= i; j...
wp_图论与搜索
图论与搜索 DFS 深度优先搜索 用途:枚举、路径搜索、连通性。 常见坑:注意回溯还原(如标记数组清零),加剪枝防超时。 小猫爬山 1234567891011121314151617181920212223242526int n, w, ans = 20;vector<int> lcs(20);void dfs(int stepnum, int lcnum, const vector<int> &cats) { if (lcnum >= ans) return; if (stepnum == n) { ans = lcnum; return; } for (int j = 1; j <= lcnum; j++) if (lcs[j] + cats[stepnum] <= w) { lcs[j] += cats[stepnum]; dfs(stepnum + 1, lcnum, ...
wp_数学
数学 数论 C. Fadi and LCM 今天,Osama给了Fadi一个整数 X,Fadi想知道 max(a,b)的最小值,使得 LCM(a,b)等于 X。 a和 b都应该是正整数。 LCM(a,b)是能被 a和 b整除的最小正整数。例如, LCM(6,8)=24, LCM(4,12)=12, LCM(2,3)=6。 -解题思路 - 根据题意有X=a*b 除以 gcd(a,b) - 为了让ab更小我们贪心的从根号X开始找 - 贪心数学推论->正整数 XXX,至少有一对互质因子。(他和1)->任何一个数字都可以通过质数相乘得到->LCM的取法是:对于每一个质数,取两人中指数“最高”的那个。 - 切分lcm定理:对于任何一个质因子(比如一堆2,或者一堆3),它们必须作为‘一坨’整体,要么全给 a,要么全给 b,绝对不能切开。 AC代码 123456789101112131415161718192021222324252627void solve(){ int n; cin >> n; vi prob; ...
wp_̰贪心
贪心 如上P2887 [USACO07NOV] Sunscreen就是典型的贪心,重点是如何去通过我们固定左端点的大胆尝试去实现 反悔贪心 P2949 [USACO09OPEN] Work Scheduling G (全局贪心) 我一开始的错误思路 人人都能想得到去走时间,然后将最紧急的任务先做了然后再紧急的任务里面贪心 最大的问题是:你的贪心是占用时间的,是有后效性的,万一后面有价值更高的任务他就不是期望值了 DP?时间跨度巨大:Di≤109D_i \le 10^9Di≤109。任务数量(N)较大:N≤105N \le 10^5N≤105。离散化时间之后依然n方 正确思路以及为什么: 以后你在做题时,如果满足以下特征,请立刻想到反悔贪心: 选择带有顺序性(或者可以排序)。 当前的选择会影响后续的资源(比如占用了时间、金钱)。 我们在乎的是“数量”或者“总价值”。 如果发生冲突,我们可以通过“撤销”之前的某个劣质选择,来接纳当前的优质选择,且这种交换一定是不亏的(甚至更赚) AC代码 12345678910111213141516171819202...
wp_基础算法与杂
基础算法 二分搜索 用途:答案单调时逼近最优解。 常见坑: 最小值模板:if(check) r=mid else l=mid+1。 最大值模板:if(check) l=mid else r=mid-1。 注意边界(left 初始化为最大单元素)。 货运难题 1234567891011121314151617181920212223242526272829int n, k;bool check(int pans, const vector<int> &nums) { int hsh = 0, cnt = 0; for (int i = 0; i < n; i++) { if (hsh + nums[i] > pans) { cnt++; hsh = nums[i]; } else hsh += nums[i]; } return cnt <= k-1;}voi...









