题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大,则输出-1. I nput 第一行两个整数n,m,表示n个点m条边 接下来m行,每行3个整数x,y,z,表示节点x和节点y之间有一条长z的边 Output 输出一行m个整数,表示每条边的答案 Sample Input 4 4 1 2 2 2 3 2 3 4 2 4 1 3 Sample Output…
Description 给你一个无限长的数组,初始的时候都为0,有3种操作: 操作1是把给定区间[l,r][l,r] 设为1, 操作2是把给定区间[l,r][l,r] 设为0, 操作3把给定区间[l,r][l,r] 0,1反转. 一共n个操作,每次操作后要输出最小位置的0. Input 第一行一个整数n,表示有n个操作 接下来n行,每行3个整数op,l,r表示一个操作 Output 共n行,一行一个整数表示答案 Sample Input 3 1 3 4 3 1 6 2 1 3 Sample Ou…
题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 t′=t2⋯tmt1t′=t2⋯tmt1 也是 ss 的一个子串. Input 输入仅有一行,一个字符串 s(1≤lens≤300000)s(1≤lens≤300000) .字符串 ss 仅包含小写字母. Output 输出一个整数表示答案. Sample Input (样例输入1) abaac (样例输入…
题目描述 给定一个长度为\(L \le 10^9\)的环形赛道, \(n \le 10^5\)个人在上面赛艇. 每个人的速度都不相同, 假如为正则顺时针走, 否则逆时针走. 当两个人相遇时, 他们就会开火, 编号小的那个人就会挂掉出局. 当只剩下一个人时, 这个人就获得胜利. 问: 多久以后游戏结束. Solution 考虑什么时候游戏结束: 最后仅剩的两个人相遇, 则一个挂掉, 另一个胜利. 因此我们只要得到最后是哪两个人相遇即可. 考虑每次相遇的只能是位置相邻的两个人, 因此我们把相邻两个人…
题目大意 给你一个序列\(a_1, a_2, ..., a_n\). 我们令函数\(f(n)\)表示斐波那契数列第\(n\)项的值. 总共\(m\)个操作, 分为以下两种: 将\(x \in [L, R]\)中的所有\(a_x\)加上一个数\(k\); 询问\(\sum_{x \in [L, R]}f(a_x)\) \(n \le 10^5\) \(m \le 10^5\) Solution 我们靠考虑斐波那契数列的转移矩阵: \[ [f_{a + b - 1} \ f_{a + b}] = […
noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君将进行N−1次操作,来把这棵蓝色的树变成红色的树.* 选一条仅包含蓝色边的简单路径,并删除这些边中的一条.* 然后在路径的两个端点中间连一条红色的边.他的目标是,对于每一个i,都有一条红色的边连接ci和di.现在请你判断是否可能达成他的目标. Input 题目数据按一下格式从标准输入输出输入: NN…
Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同于前两个点子树上, 也有可能在重心往上走可以到达的位置上. 定义数组\(f[i][j]\)表示在以\(i\)为根的子树下与\(i\)的距离为\(j\)的节点个数; \(g[i][j]\)表示在以\(i\)为根的子树下, 有多少个点对满足如下条件: 这个点对到它们LCA的距离相同, 我们假设其为\(d…
Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同于前两个点子树上, 也有可能在重心往上走可以到达的位置上. 定义数组\(f[i][j]\)表示在以\(i\)为根的子树下与\(i\)的距离为\(j\)的节点个数; \(g[i][j]\)表示在以\(i\)为根的子树下, 有多少个点对满足如下条件: 这个点对到它们LCA的距离相同, 我们假设其为\(d…
Problem A: Colorful Balls Description Snuke放了N个一排彩色的球.从左起第i个球的颜色是ci重量是wi她可以通过执行两种操作对这些球重新排序操作1:选择两个相同颜色的球,假如他们的重量和小于等于X,交换两个球的位置操作2:选择两个不同颜色的球,假如他们的重量和小于等于Y,交换两个球的位置求我们总共可以得到多少种 不同的颜色序列?对答案取109+7的模 Input N X Yc1 w1. . .cN wN Output 输出答案. Sample Input…
Solution 首先审清题意, 这里要求的是子串而不是子序列... 我们考虑用1表示p, -1表示j. 用sum[i]表示字符串前\(i\)的前缀和. 则我们考虑一个字符串\([L, R]\)有什么要求: \(\forall x \in [L, R]\)满足\(sum[x] \ge sum[L - 1]\). 我们分别从前往后和从后往前求出以每个位置为开头的最长合法子串, 然后扔进树状数组里面查询即可. 至于怎么求以每个位置为开头最长合法子串, 我们考虑用一个单调栈来维护: 从前往后扫每个位置…
Solution 这道题有两个关键点: 如何找到以原串某一个位置为结尾的某个子序列的最晚出现位置 如何找到原串中某个位置之前的所有数字的最晚出现位置中的最大值 第一个关键点: 我们注意到每个数字在\(M\)和\(L\)中最多只会出现一次. 以\(M\)为例, 我们从前往后逐位在原串中匹配, 数组f[i]表示\(M\)的前\(i\)位在原串中当前位置之前的最晚出现位置. 假设当前数字\(x\)在\(M\)中出现位置为\(p\), 则 \[ f[p] = \begin{cases} f[p] = i…
Solution 场上的想法(显然是错的)是这样的: 我们假设棋子是一个一个地放置的, 考虑在放置棋子的过程中可能出现哪些状态. 我们令有序整数对\((i, j)\)表示总共控制了\(i\)行\(j\)列的情况, 我naive地认为一个状态要么不出现, 要么只出现一次. 于是用\(f[i][j]\)来表示出现的概率, 直接进行DP. 然后我用随机函数对拍, 发现是WA的... 考虑问题出现在了哪里: 一个状态实际上是可以出现多次的. 比如说我们考虑分别控制了两行两列的状态: 两行两列产生4个交点…
题目大意 给你一棵树, 每个点有一个点权. 有两种操作: link / cut 修改某个点的点权 每次操作后, 你要输出以下答案: 在整棵树中任意选两个点, 这两个点的LCA的期望权值. Solution 我们考虑每个点作为LCA的概率: \[ P(u为LCA) = \frac{sz[u]^2 - \sum_{v为u的子节点} sz[v]^2}{n^2} \] 所以我们的答案为 \[ \begin{aligned} E &= \frac{\sum_{每个节点u} (sz[u]^2 - \sum_…
Solution 傻X题 我的方法是建立后缀后缀树, 然后在DFS序列上直接二分即可. 关键在于如何得到后缀树上每个字符对应的字节点: 我们要在后缀自动机上记录每个点在后缀树上对应的字母. 考虑如何实现, 我们在后缀自动机上的每个状态上, 记录其所对应的在字符串中的位置, 减去其父亲节点的长度即可得到每个节点对应的后缀树上的字符. #include <cstdio> #include <cstring> #include <algorithm> using namesp…
Solution 这到题目有意思. 首先题目描述给我们提供了一种非常管用的模型. 按照题目的方法, 我们可以轻松用暴力解决20+的问题; 关键在于如何构造更大的情况: 我们发现 \[ [(n + n) / n] \times [(n + n) / n] \times [(n + n + n) / n] + (n - n) \times (n + n + n + ... + n) = 24 \] 因此只要有\(n \ge 15\), 就一定有解, 并且可以按照上述方法凑出来. 至于\(n \le…
题目大意 你们自己感受一下原题的画风... 我怀疑出题人当年就是语文爆零的 下面复述一下出题人的意思: 操作1: 给你一个点集, 要你在trie上找到所有这样的点, 满足点集中存在某个点所表示的字符串是这个点所表示字符串的后缀. 把这些点的权值加一: 操作2: 给你一个点集, 要你在trie上找到所有这样的点, 满足这个点所表示的字符串是点集中某个点的后缀; 求所有这些点的权值之和. 做法很显然, 我们先建立出后缀树, 在后缀树上树剖, 剖出的序列用线段树维护即可. 注意树剖得到的序列中, 一个…
Solution 考虑给定一个\(n\), 如何求\(1\)到\(n\)的正整数中有多少在队列中. 不难注意到我们只需要处理质数次方的情况即可, 因为合数次方会被其因数处理到. 同时我们考虑到可能存在两个正整数\(a\)和\(b\)使得\(a^2 = b^3\), 因此我们要将这种情况减去, 也就是相当于要减去可以被表示为\(x^6\)的数的个数. 这样一来, 按照莫比乌斯函数容斥即可. 然后考虑如何求序列的第\(n\)项: 一种方法是二分; 同时我们也考虑到由于不在队列中的正整数十分稀疏, 因…
Solution 分数规划经典题. 话说我怎么老是忘记分数规划怎么做呀... 所以这里就大概写一下分数规划咯: 分数规划解决的是这样一类问题: 有\(a_1, a_2 ... a_n\)和\(b_1, b_2 ... b_n\)这样一些值(其中\(b\)严格大于零), 其中\(a\)和\(b\)之间存在某种联系; 要你决策出每个\(a_k\), 使得 \[ ans = \frac{\sum_{x = 1}^n a_x}{\sum_{x = 1}^n b_x} \] 取得最大值或最小值. 考虑怎样…
Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \le j} last[j]\). 而我们的答案就等于 \[ sum_{i = 1}^n (i - (max_{1 \le j \le i} last[j])) = \sum_{i = 1}^n i - \sum_{i = 1}^n max_{1 \le j \le i} last[j] \] 第一项…
Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内容题解已经写得很详细了, 直接看题解吧: 线性的LIS的经典做法:从左往右扫并维护f[x]表示当前长为x的LIS的最后一个数最小是多少,易证f[x]必定递增,每次新加一个数y,则在f中二分查找最小的x使得f[x]>=y,若找到则将f[x]设为y,否则在f末尾加上y.最后f的长度即为答案. 答案一定是…
Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \begin{array}{} k \\ n - m + 2x \end{array}{} \right) \] 考虑到\(m\)非常大, 而\(k\)却比较小, 我们尝试将\(x\)的\(m\)相关转化为\(k\)相关. 我们用如下现实意义来考虑: 令\(N = n - m\), 则我们相当于有两堆…
Solution 这是一道好题. 考虑球体的体积是怎么计算的: 我们令\(f_k(r)\)表示\(x\)维单位球的体积, 则 \[ f_k(1) = \int_{-1}^1 f_{k - 1}(\sqrt{1 - r^2}) dr \] 然而\(f_{k - 1}(\sqrt{1 - x^2})\)并不容易处理, 我们又注意到\(k\)维球体的体积可以表示为\(a \pi r^k\), 因此\(f_k(\sqrt{1 - r^2}) = f_k(1) \times (1 - r)^{\frac…
Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. 考虑如何建图: 我们对每个景点分别建一个点, 源点连向左岸的景点, 右岸的景点连向汇点, 边的容量都是2, 这限制了一个点最多只能连两条边; 我们再将一个点拆成\(k\)个, 每个代表一个连入的边的权值, 也就是说对于连入一个点的所有边, 都连在代表该边的权值的点上; 一个景点与其拆成的\(k\)…
Solution 这道题告诉我们, 不能看着数据范围来推测正解的时间复杂度. 事实证明, 只要常数足够小, \(5 \times 10^6\)也是可以跑\(O(n \log n)\)算法的!!! 这道题有两种思路. 比较容易想到的(也是我考场上想的)一种是: 把所有任务按照权值从大到小排序, 从权值大的开始安排, 将其安排在尽可能靠后的位置; 假如位置不够, 安排不下, 则可停止. 但这样非常难统计答案, 我想到的做法是用线段树的分裂与合并来维护整个区间. 但考虑到时间复杂度以及常数大小, 还是…
Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大小非常不熟练. 正确的做法是每个点开两个变量size和add, 分别表示在splay中以这个点为根的所有点所在的子树的点的数量, 以及以当前点为根的子树由虚边贡献的点的数量. #include <cstdio> #include <cctype> #include <algori…
Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格, 从前往后扫描. 假设我们已经知道了到前一天的最优策略, 考虑到当前这一天的最优策略: 假如手上还有股票, 那么一定是要把它卖掉的; 假如已经没有股票了, 那么我们就在原本打算卖出的股票以及这一天的股票中选出股价最低的买入. 用优先队列维护股价, 从第一天往后扫描即可. #include <cst…
Solution 智障暴力题, 每个点维护一下子树信息, 树剖就好了. 我居然还傻了写了一发毛毛虫... #include <cstdio> #include <cctype> #include <vector> #include <algorithm> #include <cstring> #define vector std::vector #define max std::max #define min std::min #define s…
Solution 我们把遇到一个旗子或者是遇到一个敌人称为一个事件. 这一题思路的巧妙之处在于我们要用\(f[i]\)表示从\(i\)这个事件一直走到终点这段路程中, \(i\)到\(i + 1\)这段路只被经过一次的概率. 分类讨论: \(i + 1\)是一个敌人, 则\(f[i] = f[i + 1] \times p[i + 1]\) \(i + 1\)是一个旗子, 则 \[f[i] = f[i + 1] \\ + f[i + 1] \times (1 - f[i + 1]) \times…
Solution 我们发现, 对于一条路径来说, 花费总时间为\(ap + q\), 其中\(p\)和\(q\)为定值. 对于每个点, 我们有多条路径可以到达, 因此对于每个区间中的\(a\)我们可以找到不同的\(p\)和\(q\)使得答案最优. 因此对每个点维护一个凸包即可. 同时我们注意到\(0 \le a \le 1\), 因此凸包中的元素不会无限增长. 考虑如何构建这个凸包? SPFA即可. 具体实现见代码. #include <cstdio> #include <cctype&…