内部考试总结
Posted iamafool
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部考试总结相关的知识,希望对你有一定的参考价值。
2019年8月5日星期一
Kos
题目描述
有\(n\)个人,他们之间将会有\(m\)场比赛(两个人之间可能有多场比赛,但这些比赛的结果不一定完全相同),问获胜场次最多的人获胜的场次数最少
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n\le 10^4,0\le m\le 10^4\)
正解算法
建立二分答案,对猜测解\(x\),考虑建立最大流模型
对每场比赛和每个人都建立一个点,从源点向每场比赛连一条容量为\(1\)的边,每个选手向汇点连一条容量为\(x\)的边,每场比赛都向参赛选手连一条容量为\(\infty\)的边
若这个图的最大流为\(m\),则\(x\)为可行解,否则为错解
投票
题目描述
有\(n\)个人,他们之间有\(m\)对双向的朋友关系(不会有重复的朋友关系,也不会有一个人与自己为朋友)
现在有一场投票,每个人可以选择投赞成票或反对票,每个人一开始已经有一个意愿
若一个人的实际投票与他的意愿相悖,或与他的一个朋友的实际投票不同,那么他会产生\(1\)的满意度(一个人可能产生超过\(1\)的不满意度),问最小的总不满意度之和为多少
限制范围
\(Time:1000ms\quad Space:512MB\)
\(2\le n\le 300,1\le m\le \frac n(n-1)2\)
正解算法
首先从源点向所有意愿为赞成的人连一条容量为\(1\)的边,从所有意愿为反对的人向汇点连一条容量为\(1\)的边,再将一对朋友互相连一条容量均为\(1\)的双向边
如果这样建图,那么违背意愿就要割掉与源汇的连边,否则要将与所有不同选择的朋友的连边断掉,因此这个图的最小割即为答案
炮塔
题目描述
有一个\(n\times m\)的地图,地图上的每一个位置要么是空地,要么是炮塔,要么有\(a_i,j\)个怪物
对于每个炮塔,已经给出它可以瞄准的方向(上下左右中的一个),该方向上的所有位置都属于炮塔的射程范围,但每一个炮塔只能够攻击射程范围内的一个位置,或者不进行攻击,但如果攻击,那么炮塔攻击到的位置上所有的怪物都会被消灭
出于安全考虑,保证不存在一个炮塔的射程范围覆盖另外一个炮塔,即对于任意一个炮塔,它瞄准方向上的所有位置都不存在另外一个炮塔
如果把炮塔的起点和终点称为炮弹的运行轨迹,为了保证攻击的稳定,不允许两条轨迹相交,包括起点和终点
现在问你最多可以消灭多少怪物
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n,m\le 50,0\le a_i,j<1000\)
正解算法
由于两个横向的炮塔与两个纵向的炮塔是互相不影响的,所以考虑将横向的炮塔与纵向的炮塔拆开,建立二分图
如果一个炮塔不会被其他炮塔影响,那么只要贪心考虑可攻击位置上的最优位置即可,因此我们只需要考虑哪些会被影响的炮塔
考虑最小割,若两个炮塔到它们的最优攻击点的路径相交,那么一定为一个炮塔不越过相交点,另一个越过相交点,这样只要从两个炮塔向代表相交点的点连一条容量为“如果不越过相交点,实际的最大收益比攻击方向上所有位置的最大收益的相差值”的边(横向炮塔的连边方向为从炮塔到相交点,纵向炮塔则相反)
但是直接这样连边很有可能会错(原因:两个炮塔可能会经过多个不同的相交点,但这些相交点本不应经过,使答案错误),因此要将横向边所连接的点与纵向边所连接的点分开,并从横向点向纵向点连一条容量为\(\infty\)的边,这样每次一次只会经过一个相交点
这个图的最小割即为答案与贪心最大值的差
选数
题目描述
有\(n\)个正整数,需要从中选出一些数,使得这些数的和最大
但是如果其中两个数\(a,b\)满足\(\exists c\in \mathbb N,a^2+b^2=c^2\)且\(gcd(a,b)=1\),那么这两个数不能同时选择
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n\le 3000\)
正解算法
首先预处理出这些数两两之间是否不能同时选取
可以发现,这个不能同时选取的关系所构成的图一定是一个二分图,因为
2019年8月6日星期二
质数翻转
题目描述
有无穷多张卡牌排成一排,依次编号为\(1,2,3,\cdots\)
一开始仅有\(x_1,x_2,x_3,\cdots,x_n\)正面朝上,其他的牌均反面朝上
现在可以进行这样一个操作:选择一个奇素数\(p\),然后选择连续\(p\)张牌,将其翻面
现在问使得所有牌变为反面朝上的最少操作次数
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n\le 100,1\le x_1<x_2<\cdots<x_n\le 10^7\)
正解算法
考虑将序列差分,一张牌与下一张牌的状态不同则为\(1\),否则为\(0\),这样,区间翻转操作则变为了单点操作
由弱化版的哥德巴赫猜想可知:
- 当区间长度为偶数时,翻转这个区间的最小代价为\(2\)
- 当区间长度为奇素数时,翻转的最小代价为\(1\)
- 若上面两种情况都不是(奇合数或\(1\)),那么最小代价为\(3\)
看上去要一般图带权最大匹配,但实际上不要
仔细分析可知,将一个长度为奇合数或\(1\)的区间翻转的情况最多只会出现一次
因此我们可以采用贪心做法,先尽量翻转长度为奇素数的区间,再翻转长度为偶数的区间,最后如果还剩下\(1\),则直接匹配(因为最后最多只留下两个\(1\))
翻转长度为奇素数的区间的方法:将\(1\)的位置按奇偶分成两个集合,再在这个新图上跑二分图匹配
翻转长度为偶数的区间的方法:同样将\(1\)的位置按奇偶分成两个集合,然后在两个集合内部两两配对即可
偶字符串
题目描述
我们定义“偶字符串”为可以通过连接两个相等的字符串得到的字符串
对一个非空字符串\(s\),设\(f(x)\)为可以通过将一个或多个字符添加到\(s\)的末尾得到的最短的偶字符串
现在给定一个偶字符串\(s\),问在调用\(f(x)\rightarrow s\)无数多次后,对每种字符\(c\),\(c\)在\([l,r]\)中的出现次数
限制范围
\(Time:2000ms\quad Space:256MB\)
\(2\le |s|\le 2\times 10^5,1\le l\le r\le 10^18,s为偶字符串\)
题目描述
首先我们设\(s=t^2,t=aba=ca,g(t)^2=f(s)\),那么有:
\[
t=ca\g(t)=cac=tc\g(g(t))=cacca=tct=g(t)+t\g(g(g(t)))=caccacac=tcttc=g(g(t))+g(t)
\]
可以发现\(g(t)\)的变化趋势为类似斐波那契数的变化方式,因此我们可以按斐波那契数为端点分段计算
随机排列
题目描述
给定两个长度相等的\(01\)串\(A,B\),且有\(count_1(A)=count_1(B)\)
现在有序列\(S=\i\mid A_i=1\,T=\i\mid B_i=1\\),并将其随机打乱,然后按\(i\)从小到大依次执行\(swap(A_S_i,A_T_i)\)
问所有操作执行完后,\(A=B\)的概率\(p\),要求输出\(p\times (n!)^2\ mod\ 998244353\)(其实也就是输出合法方案数)
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le |A|=|B|\le 10^4,|S|=|T|>0\)
正解算法
实际上要输出的就是满足条件的方案数
首先可以发现,交换的方式一定是形成\(\cdots ,1,1,0,1,1,\cdots\)(只有一个\(0\)的循环)或\(\cdots ,1,1,1,\cdots\)(全是\(1\)的循环)
尝试DP,设\(dp(i,j)\)为凑成\(j\)个循环,使用了\(i\)个交换两个\(1\)的位置对的方案数,那么有\(dp(i,j)=(dp(i-1,j)\times i+dp(i,j-1)\times j)\times j\)
资源采集
题目描述
给定一个含\(n\)个点的、以\(1\)为根的有根树,\(i\)号点的父亲节点为\(f_i\),与父亲节点的距离为\(d_i\)
每个点都有一口能量井,第\(i\)个点的能量井每单位时刻吸取能量值为\(v_i\),最大储量为\(l_i\)
现在有\(q\)次采集过程,第\(i\)次采集将里节点\(x_i\)距离不超过\(k_i\)的所有能量井的能量值采集完,要求输出采集到的能量值的总和
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n,q\le 52501,1\le v_i,l_i,d_i,t_i,k_i\le 10^9\)
正解算法
将每个节点的DFS序做一维坐标,在树上的深度为第二维坐标,可以发现每次询问都是询问了一个矩形
将每个节点在平面上的对应点插入一个K-D tree中,并在K-D tree的每个节点上建一棵线段树
考虑每个点所需要的的充满时间,每次查询时分类讨论一下,线段树暴力合并维护
2019年8月7日星期三
字符串复制
题目描述
有一个字符串操作\(a\rightarrow b\),方式为\(b_i\in\b_i-1,a_i\\)
现在问字符串\(S\)至少要经过几次操作变为另一个字符串\(T\)
如果无解,请输出-1
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le |S|=|T|\le 10^6\)
正解算法
首先将字符串操作转化为在矩形中折线尽可能靠右移动
贪心算法,如若遇到一条折线不能再向前了,就增加一层
反转
题目描述
对于一个正整数\(n\),我们定义它的反转数为将\(n\)在十进制下所有数位(不包括前导零)倒序摆放后的新数字,记为\(rev(n)\)
现在给定正整数\(d\),问有多少个正整数\(n\)满足\(rev(n)=n+d\)
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le d<10^9\)
正解算法
首先可得:若\(9\nmid d\),那么一定无解
可以发现,对于任意一个满足\(rev(n)>n\)的\(n\),一定有:
\[
10^\left\lfloor\frac\log_10n2\right\rfloor+1-10^\left\lfloor\frac(\log_10n)-12\right\rfloor\le rev(n)-n\le 10^\lceil\log_10n\rceil-10^\lceil\log_10n\rceil-1-10^\left\lfloor\frac\log_10n2\right\rfloor+1-10^\left\lfloor\frac(\log_10n)+12\right\rfloor+2
\]
那么我们可以限制\(n\)的搜索范围
然后我们可以DFS搜索\(n\)的前一半数码,推出后一半数码,再确认是否合法
注意,当在DFS的中间一步中发现不满足条件了,就直接剪枝,不再向下搜索
排列
题目描述
给定一个由\(n\)个正整数所组成的序列,第\(i\)个数字为\(A_i\),有两个人在用这些数字玩一个游戏,游戏规则如下:
- 先手将序列任意打乱为一个新序列
- 后手可以将相邻且互质的两个数交换,此操作可以进行任意多次
先手的目标为最后序列的字典序尽量小,后手的目标则相反,且两人均绝对聪明
问最后序列的字典序最小时,最后序列是怎样的
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n\le 2000,1\le A_i\le 10^8\)
正解算法
对任意一对不互素的数\((A_u,A_v)(A_u<A_v\or (A_u=A_v\and u<v))\),连接一条有向边\(u\rightarrow v\)
可以发现,这个图上的最大括扑序即为答案
回文串
题目描述
给定一个字符串\(s\),问在加入刚好\(n\)个任意字符后,\(s\)能组成多少个完全不同的回文串
要求对\(10007\)取模
限制范围
\(Time:2000ms\quad Space:1024MB\)
\(1\le |s|\le 400,1\le n\le 10^9\)
正解算法
2019年8月8日星期四
区间和2
题目描述
给定一个长度为\(n\)的序列\(A\)与\(q\)个询问,每次问\(A\)的\(\fracn(n+1)2\)个子段各自的子段和排序后,排名在\([L,R]\)的所有子段和的总和
限制范围
\(Time:7000ms\quad Space:128MB\)
多组数据,\(T\le 10\)
\(n\le 2\times 10^5,q\le 20,1\le A_i\le 100,1\le L\le R\le \fracn(n+1)2\)
正解算法
由于\(A_i\)均为正整数,因此查询一个排名\(x\)所对应的子段和,可以二分答案,并且枚举区间左端点,尺取法检查二分正确性解决
查询结束后可以继续用尺取法,得到排名不超过\(x\)的所有子段和的总和,即查询区间和中的前缀和,再用差分即可得解
安全路径
题目描述
给定一棵有\(n\)个点的树,边的颜色可能为红色或蓝色,问有多少个无序三元组\((x,y,z)\),使得路径\((x,y),(y,z),(x,z)\)上均有至少一条红色边
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n\le 5\times 10^4\)
正解算法
方法一
树上DP,记录在\(x\)的子树中:
- \((u,x)\)含红色边的\(u\)的数量
- \((u,v)\)含红色边,\((u,x),(v,x)\)中刚好有一条含红色边的\((u,v)\)的数量
- \((u,v),(u,x),(v,x)\)均含红色边的\((u,v)\)数量
通过上面几个数据,从而得到答案
方法二
考虑容斥原理
由于答案=所有三元组的数量-所有路径全是蓝色边的三元组数量-刚好一条路径全是蓝色边的数量
那么统计出所有蓝色连通块的大小\(S_i\),则有:
\[
Ans=\left( \beginarrayc
n\ 3\\endarray \right) -\sum\left( \beginarrayc
S_i\ 3\\endarray \right) -\sum\left( n-S_i \right) \left( \beginarrayc
S_i\ 2\\endarray \right)
\]
小朋友的笑话
题目描述
有\(n\)个集合,每个集合均有一个\(01\)状态,一开始所有集合的状态均为\(0\)
现在有\(m\)个操作,每个操作有两种可能:
- 在\([x_i-k_i,x_i+k_i]\)的集合中插入元素\(l_i\),并将集合的状态置为\(1\),但如果一个集合在插入时已经包含元素\(l_i\),则不插入,而是将这个集合的状态置为\(0\)
- 查询\([l_i,r_i]\)的集合中有多少状态为\(1\)的集合
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n,m,l_i\le 10^5\)
正解算法
对每个\(l_i\)开一个std::set
维护含有\(l_i\)的集合的区间,并且维护一个支持区间赋值、查询区间和的线段树
每次插入一个元素时,将插入区间与原来的所有区间的交集设为\(0\),其他的设为\(1\)
连通期望
题目描述
有一个含\(n\)个点\(m\)条边的无向图,每条边有权值\(z_i\)与消失概率\(p_i\)(即有\(p_i\)的概率这条边不会在实际的图中出现)
现在你需要求出在使所有点尽量连通(即每个连通块都是极大连通块)的前提下,最小权值和的期望
限制范围
\(Time:1000ms\quad Space:128MB\)
\(n\le 14,m\le \fracn(n-1)2,0<p_i<1,图中不存在重边自环\)
正解算法
设\(f(S,i)\)为点集为\(S\),且在只考虑前\(i\)条边的情况下为一个极大连通块的概率,\(g(S,i)\)为同样情况下的期望边权和,\(h(S)\)为点集\(S\)内的所有点两两之间的边都未出现的概率
按\(z_i\)从小到大枚举\(i\),按照这条边是否出现分类讨论
- 如果这条边未出现,那么所有只包含这条边的刚好一个端点的子集都要将\(f\)和\(g\)乘上\(p_i\)
- 如果这条边出现了,那么就要将所有值包含其中一个端点的子集与只包含另一个端点的子集连接起来。由于两个点集之间可能有边权更小的边,但没有在实际的图中出现,因此要加入修正量\(\frach(S_1\cup S_2)h(S_1)\cdot h(S_2)\)
最后统计答案时直接枚举子集即可
2019年8月9日星期五
括号匹配
题目描述
给定一个长度为\(n\)的括号序列\(S\),要求交换其中两个括号任意次,使得\(S\)合法,问最少操作次数
若无解,输出-1
限制范围
\(Time:1000ms\quad Space:128MB\)
\(1\le n\le 10^5\)
正解算法
首先易得,无解的充要条件为“左右括号数量不等”
我们可以模拟,从左到右扫描,每次遇到一个未匹配的右括号,就将这个右括号与最右边的左括号交换,可证这样一定为解
再考虑未匹配右括号数量的变化,可知当扫描时未匹配右括号最多有\(x\)个时,答案为\(\left\lceil\frac x 2\right\rceil\)
种树
题目描述
给定一棵有\(n\)个节点的二叉树,点有点权\(w_i\),要求维护几种操作共\(m\)次:
- 翻转以\(x\)为根的子树
- 将\(x\)的点权改为\(y\)
- 询问如果按照BST(二叉搜索树)的方式查询节点\(x\),是否能够查到\(x\)
注:BST查询方式为“比点权小走左子树,比点权大走右子树,等于点权直接返回”
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n,m\le 10^5,1\le w_i\le 10^9\)
正解算法
由于一个点能够被查到的充要条件为:到根的路径上,所有左父亲都比右儿子小,所有右父亲都比左儿子大
修改操作相当于更新\(3\)个合法/非法状态,翻转操作相当于将所有状态取反
树链剖分,然后线段树维护每条边所代表的父子关系是否合法即可
树句节狗提
题目描述
给定一棵有\(n\)个点的有根树,根节点为\(1\),每个点都有点权\(a_i\),边的长度均为\(1\)
现在有\(q\)个询问,每个询问均形如:以\(x\)为根的子树内,与\(x\)距离至少为\(k\)的所有点的点权之和
限制范围
\(Time:2000ms\quad Space:256MB\)
压缩输出,给定参数\(lim\),要求输出\(\left\lceil\frac nlim\right\rceil\),第\(i\)个数为\(\bigoplus_j=(i-1)lim+1^\min(q.i\cdot lim)ans_j\)
\(1\le n,q\le 2525010,1\le a_i\le 52501,k\ge 0,lim\le n\)
\(\forall i,fa_i<i\)
正解算法
先将询问离线,原树进行长链剖分
对每条链都从低往高扫描,每个点均维护所计算的子树中深度至少与这个点深度相等的所有点的点权和
每次加入一条新链时,直接暴力合并两条链的答案
2019年8月10日星期六
红树与蓝树
题目描述
有一棵含\(n\)个点的树\(A\),一开始所有的边都是蓝色
现在要进行按顺序如下操作\((n-1)\)次:
- 选择一个只含有蓝色边的简单路径
- 移除此路径上的一条边
- 在路径的两个端点之间连一条红色边
问是否能够将\(A\)变为一棵仅由红色边构成的树\(B\)
限制范围
\(Time : 1000ms\quad Space:256MB\)
\(2\le n\le 10^5\)
正解算法
考虑如何从树\(B\)倒推回树\(A\)
考虑最后一条红边,可以发现这条红边一定与一条蓝边重合,将这条边的端点合并后(倒推一步)产生的新树一样满足这个结论
再考虑优化:我们无需将两个点的所有连边合并,只要将度数较小的点的所有连边全部连向度数较大的点,并且用并查集维护缩点后的代表点即可,找公共边可以用Hash或std::set
众数MAX
题目描述
现在有两个长度为\(n\)正整数序列\(a,b\),问将\(a,b\)任意排列后\(\a_i+b_i\\)的众数的最大出现次数是多少
限制范围
\(Time : 1000ms\quad Space:512MB\)
\(1 \le n,a_i,b_i \le 10^5\)
正解算法
设\(As(x)=|\i\mid a_i=x\|,Bs(x)=|\i\mid b_i=x\|\)
若最后的众数为\(p\),那么答案为下式:
\[
\beginalign
ans_p&=\sum_g=1^p-1\min(As(g),Bs(p-g))\&=\sum_i=1^n\sum_j=1^p-1[As(j)\ge i]\times [Bs(p-j)\ge i]
\endalign
\]
这个式子肯定不能直接FFT,考虑分块
设定阈值\(k\),暴力统计所有\(\min(As(j),Bs(p-j))>k\)对答案的贡献,FFT计算\(\min(As(j),Bs(p-j))\le k\)时的答案,再综合两部分答案即可
如何求出\(p\)的值?枚举即可
~K Perm Counting
题目描述
要求求出有多少个\(1\sim n\)的排列\(a\),使得\(\forall i,|a_i-i|\ne k\)
答案对\(924844033\)取模
限制范围
\(Time : 1000ms\quad Space:512MB\)
\(1\le k < n \le 2000\)
正解算法
设\(f(x)\)为至少有\(x\)个位置不合法的方案数,那么答案为\(\sum_i=0^n(-1)^i f(i)(n-i)!\)
考虑如何计算\(f(x)\)
将每个位置和每个值都作为一个点,则有\(2n\)个点,如果第\(i\)个位置上博客园天\(j\),就在位置\(i\)与值\(j\)之间连边,这样就能得到一个二分图:
问题即为在这个二分图中选\(i\)条边,使得任意两条边均没有公共端点的方案数
可以发现,这里可以变为多条链,那么枚举点和边,DP计算即可
Monkey and Tree
题目描述
有一棵含\(n\)个点的树,每条边都有正整数长度\(l_i,j\),同时有\(m\)个点对\((a_i,b_i)\)
现在需要在所有点对中选出两个点对,使得\((dist(a_i,a_j)+dist(b_i,b_j))\)最大
限制范围
\(Time:4000ms\quad Space:512MB\)
\(1\le n,m \le 10^5,1\le a_i,b_i\le n,1\le l_i,j\le 10^9\)
正解算法
2019年8月11日星期日
伟大的航线
题目描述
有一条东西向(平行于\(x\)轴方向,在\(y=0\)与\(y=nw\)之间)的的河流,它被分割为\(n\)条等宽的航道,每条航道的宽度均为\(w\)
同时第\(i\)条航道上有\(m_i\)条向同一个方向行驶的船只,其中第\(j\)条船只的船头位置为\(p_i,j\),长度为\(l_i,j\),速度为\(u\)(所有船只的速度均相等)
现在在\((0,0)\)处有一个人想要向\(y\)轴正方向以\(v\)的速度匀速移动,开始时间必须在\([t_1,t_2]\)之间,且不碰到任何一艘船,求可以安全到达河对岸的出发时间的最大区间
限制条件
\(Time:1000ms\quad Space:128MB\)
\(1\le n \le 10^5,1 \le w \le 1000,1\le u,v \le 100,0\le t_1<t_2\le 10^6.\sum m_i \le 10^5,1\le l_i,j\le 1000,-10^6\le p_i,j\le 10^6\)
正解算法
对所有船只计算出将会与这艘船相撞所需要的出发时间区间,任何找到不包含所有这些区间的最大区间即可
注意:计算时必须加入\((-\infty,t_1)\)和\((t_2,\infty)\)
汽油补给
题目描述
有\((n+1)\)个排成一线的城市,编号为\(0\sim n\),其中\(i\)号城市到\((i+1)\)号城市的距离为\(d_i\),城市中的加油站的油价为\(p_i\),每一单位油可以满足一辆车跑一单位的距离
有一辆油箱容量为\(t\)的车(一开始油箱里面没有油)要从\(0\)号城市走到\(n\)号城市,求最小总花费
限制条件
\(Time:1000ms\quad Space:128MB\)
\(2\le n\le 10^5,1\le t\le 10^9\)
正解算法
首先判断是否有解,可知有解的充要条件为\(\forall i,d_i\le t\)
然后枚举当前的城市,利用单调队列,计算当前的城市的油价一直到后面哪个城市的前面是最小的,中间这一段的油就需要贪心地在当前城市加
抽卡大赛
题目描述
有\(n\)个人要抽卡,第\(i\)个人抽卡有\(m_i\)种可能,抽到\((a_i,j,c_i,j)\)的概率为\(\fracp_i,j\sum_jp_i,j\)
设第\(i\)个人抽到了第\(s_i\)张卡,那么将\(a_i,s_i\)排序后,\(a_i,s_i\)第\(k\)大的将获得\(\fracv_kc_i,s_i100\)的收入
要求求出每个人的期望收入,要求对\((10^9+7)\)取模
限制范围
\(Time:1000ms\quad Space:256MB\)
\(1\le n,m_i \le 200,1\le a_i,j\le 10^9.\forall i_1\ne i_2\or j_1\ne j_2\quad a_i_1,j_1\ne a_i_2,j_2,0\le c_i,j\le 100,1\le p_i,j,v_k\le 1000\)
正解算法
首先枚举所需要计算的人\(s\)
设在\([1,x]\)中\(s\)能够赢\(y\)个人的概率为\(f(s,x,y)\),\(s\)能够赢\(t\)的概率为\(g(s,t)\),那么有:
\[
f(s,x,y)=g(s,x)f(s,x-1,y-1)+(1-g(s,x))f(s,x-1,y)\g(s,t)=\sum \fracp_s,i\sump_s,i\cdot\frac\sum_a_s,i>a_t,jp_t,j\sum p_t,j
\]
我们可以从小到大枚举\(a_i,j\),每次加入新的卡牌时就只会更新一对\(g(i,j)\),这样就能快速得到所有的\(g(i,j)\),从而得到所有的\(f(s,x,y)\)与答案期望
区间最大子段和
题目描述
给定一个长度为\(n\)的序列\(A\),要求维护\(m\)次操作,每种操作可能为:
- 把区间\([l,r]\)的所有数加上\(x\)
- 查询区间\([l,r]\)内的最大子段和(子段可以为空)
限制范围
\(Time:4000ms\quad Space:256MB\)
\(1\le n,m \le 10^5,|a_i|\le 2\times 10^9,0\le x\le 10^6\)
正解算法
2019年8月12日星期一
zigzag
题目描述
有\(\fracn(n+1)2\)个点排列成一个等边三角形,每条边由\(n\)个点组成
若第\(i\)行的左起第\(j\)个点被表示为\((i,j)(1\le j\le i\le n)\),那么\((i,j)\)左下方的点为\((i+1,j)\),右下方的点为\((i+1,j+1)\)
现在需要画\(m\)条折线\(\L_i\\),每条折线\(L_i\)均依次连接了\((1,x_i,1),(2,x_i,2),\cdots ,(n,x_i,n)\),且有\(x_i,j+1=x_i,j\)或\(x_i,j+1=x_i,j+1\)
不仅如此,\(L_i+1\)的任一部分都不能\(L_i\)更靠左,即\(\forall i,j\quad x_i,j\le x_i+1,j\)
另外,有\(k\)个限制形状的条件必须被满足,每个条件形如\((a,b,c)\),表示\(x_a,b+1=x_a,b+c\)
求画出这\(m\)条折线的方案数,要求对\((10^9+7)\)取模
限制范围
\(Time:4000ms\quad Space:256MB\)
\(1\le n,m \le 20,0 \le k \le (n-1)m,1\le a\le m,1 \le b \le n-1,c=0\ or\ 1,每对(a,b)只会出现一次\)
正解算法
考虑DP求出方案数
设\(sol(i,j,S)\)代表考虑到第\(i\)条折线\(L_i\),前\(j\)个位置的移动方式与\(S\)这个二进制串所代表的折线相同(且\(L_i\)的任一部分都不能比\(S\)所代表的折线更左),则转移方式如下:
- 若下一位的移动方式与\(S\)相同,那么\(sol(i,j,S)\)可转移到\(sol(i,j+1,S)\)
- 若下一位需要选择向左(即为\(0\)),而\(S\)的下一位为\(1\),那么此时的答案一定不合法,直接不转移
- 若下一位需要选择向右(即为\(1\)),而\(S\)的下一位为\(0\),那么考虑将\(S\)中最靠近第\(j\)为的\(1\)移动到第\(j\)位(也就是\(S\)的下一次右转提前),如果没有\(1\)了,就直接将\(S\)的第\(j\)位改为\(1\),这就能构造出新的限制串\(S'\),将\(sol(i,j,S)\)转移到\(sol(i,j+1,S')\)即可
- 当\(L_i\)的所有位均考虑完后,直接将\(sol(i,n-1,L_i)\)转移到\(sol(i+1,0,L_i)\)
flags
题目描述
有\(n\)面旗,第\(i\)面旗都只能放在\(a_i\)或\(b_i\)这两个位置中的一个上,求这些旗帜两两之间最小距离的最大值
限制范围
\(Time:2000ms\quad Space:512MB\)
\(2\le n\le 10^4,1\le a_i,b_i\le 10^9,a_i,b_i\in\mathbbN\)
正解算法
首先考虑二分答案,将原问题转化为存在性问题
然后将每面旗\(i\)选取哪个位置作为\(01\)状态,中间问题则可转化为2-SAT问题
由于边数较大,不能直接建边,但是发现与某个位置牵制的所有位置均是连续的,那么可以线段树优化建图
graph
题目描述
有一个含\(n\)个点\(n\)条边的有向图,顶点编号从\(1\)到\(n\)
这个图的\(n\)条边分别是\((p_1,1),(p_2,2),\cdots,(p_n,n)\),并且图是弱连通的(即任意两点间都可以经过若干原边或反向边互相到达)
我们需要为这个图中的每个点分配一个权值\(a_i\),并且满足以下条件:
- \(\forall i,a_i\in\mathbbN\)
- \(\forall i,a_i\ne a_p_i\)
- \(\forall i,x\in[0,a_i)\quad\exists j,a_j=x\and p_j=i\)
问是否存在合法的分配方案
限制范围
\(Time:2000ms\quad Space:512MB\)
\(2\le n\le 2\times 10^5,1\le p_i\le n,p_i\ne i\)
正解算法
可以发现,原图一定是一个基环外向树
发现\(a_i\)相当于原图的SG函数的值
考虑到图为一棵树时,直接按照树上SG函数的推导方式DP
再尝试考虑基环的取值:
- 若此时所有点的\(a_i\)均相同
- 当基环为偶环时,只要隔一个点将一个\(a_i\)增加\(1\),这样一定是可行的
- 当基环为奇环时原问题一定是无解的
- 若此时有至少两个点的\(a_i\)不同,那么只要对\(\forall i,j\quad p_j=i,a_i=a_j\),将\(a_i\leftarrow a_i+1\),直到不再存在两个相邻点的\(a_i\)相同为止(这样的过程一定会在有限步后结束)
yesorno
题目描述
有\((n+m)\)个判断题,已知其中恰好有\(n\)个问题的答案为Yes
,\(m\)个问题的答案为No
,但是这\((n+m)\)个问题给出的顺序时未知的
你现在可以逐个去猜每个问题的答案,每次猜完后你都能得到这道题的正确答案
你要求出在最优策略下,答对总数的期望值,要求对\(998244353\)取模
限制范围
\(Time:2000ms\quad Space:512MB\)
\(1\le n,m\le 5\times10^5\)
正解算法
首先可以发现,最优策略一定是选择剩下问题数更多的答案
然后通过数学推导可知
2019年8月13日星期二
increasing
题目描述
我们定义通过数是“上升的”,当且仅当这个数除个位外,每一位都不超过下一位数码
现在有一个数\(n\),求\(n\)最少能拆成多少个“上升的”数的和
限制范围
\(Time:2000ms\quad Space:256MB\)
\(n\le 10^5\times 10^5\)
正解算法
首先可以看出,答案的最大不超过\(\log_10n\),因为可以每次减去最高位的数,来使长度至少减少\(1\),所以如果我们能均摊\(O(1)\)计算出答案的合法性,就可以枚举答案了
考虑对“上升数”进行分解,可发现每个“上升数”都可以分解为\(9\)个\(\frac10^b-19\)的和,问题即转化为求最小的\(k\),使得存在含\(9k\)个元素的非负整数可重集合\(\A_i\\),使得\(9n+9k=\sum_i=1^9k10^A_i\)
考虑\((9n+9k)\)的数位和\(cut(9n+9k)\),可知只要\(9k\ge cut(9n+9k)\),则此时的\(k\)一定合法,我们只要从小到大枚举\(k\),并且维护\(cut(9n+9k)\),那么就可以枚举出答案
restaurants
题目描述
街上有排成一线的\(n\)个餐馆,编号在\([1,n]\)之间,第\(i\)家餐馆与第\((i+1)\)家餐馆的距离为\(L_i\)
现在有\(m\)张优惠券,在第\(i\)家餐馆使用第\(j\)张优惠券可以得到\(W_i,j\)的的收益,每张优惠券只能用一次(也可以不用),但是每家餐馆可以同时使用多张优惠券
求从任意一家餐馆出发,\(\max(\sum W_i,j-\sum L_i)\)的值
限制范围
\(Time:2000ms\quad Space:256MB\)
\(2\le n \le 5000,1\le m\le 200,1\le A_i,W_i,j \le 10^9\)
正解算法
首先可以得到:最终走过的餐馆(不一定会使用优惠券)一定是连续的一段区间,当区间确定后,每张优惠券的使用位置以及局部最优解也以及确定了
从大到小枚举\(W_i,j\),每次更新 \(W_i,j\)为第\(j\)张优惠券的较优收益 的所有区间的答案
由于每次更新的所有区间的两个端点一定在同一个范围内,则可以变为二维区间加值、单点查询问题,将其差分化即可
coloring
题目描述
在平面直角坐标系上有一个矩形,左下角位于\((0,0)\),右上角位于\((w,h)\),矩形的边平行于坐标轴。一开始,整个矩形都是白色的
在矩形内有\(n\)个点,第\(i\)个点位于\((x_i,y_i)\),要求对每个点都进行一次下列四种操作中的任意一种:
- 将平面区域\(x<x_i\)染成黑色
- 将平面区域\(x>x_i\)染成黑色
- 将平面区域\(y<y_i\)染成黑色
- 将平面区域\(y>y_i\)染成黑色
求在所有可能的染色方案中,白色区域周长的最大值
限制范围
\(Time:4000ms\quad Space:256MB\)
\(1\le w,h\le 10^8,1\le n \le 3\times 10^5,0\le x_i \le w,0\le y_i \le h,\forall i\ne j\quad x_i\ne x_j,y_i\ne y_j\)
正解算法
可以发现这个问题可以转化为:找一个周长最大的矩形,使得矩形的内部没有点
推导可知,答案一定经过原矩形的一条中线(可能为\(x=\frac w 2\)或\(y=\frac h 2\))
不妨考虑经过\(x=\frac w 2\)的情况(经过\(y=\frac h 2\)情况可以类似地推出)
从上往下枚举下边界,用单调栈维护不同上边界时最优的上边界与下边界,线段树维护不同上边界时的最优解,更新单调栈时同步更新线段树即可
game
题目描述
有一棵含\(n\)个点的无根树,编号从\(1\)到\(n\),这棵树有\((n-1)\)条边,第\(i\)条边连接点\(a_i\)和点\(b_i\),现在在第\(i\)个点放有\(d_i\)个石子
现在有两个人进行一项游戏,规则如下:
- 一开始,先手选择一个点,并在上面放上一个木块
- 从先手开始,二人轮流进行如下操作:
- 从木块所在的节点移除一个石子
- 然后把木块往相邻的一个点移动
- 若当某个人进行操作时,木块所在的点上没有石子,那么他就不能进行操作并输掉这场游戏
在两个人都采用最优操作时,请找出使得先手必胜的所有初始放置点
限制范围
\(Time:2000ms\quad Space:256MB\)
\(2\le n \le 3000,1\le a_i,b_i\le n,0 \le d_i \le 10^9,保证输入的边恰好构成一棵树\)
正解算法
对任意点\(r\),我们考虑将\(r\)设为根时的有根树
定义\(f:x\rightarrow \0,1\\)表示在以\(x\)为根的子树内,是否能做到先手必胜,那么\(f(x)=1\)的充要条件为\(\exists y\in son(x),f(y)=0\and d_y<d_x\)
2019年8月14日星期三
第K大区间
题目描述
定义一个区间的权值为其众数出现的次数
现给出\(n\)个数,求将所有子区间的权值排序后,第\(k\)大的值为多少
限制范围
\(Time:1000ms\quad Space:128MB\)
\(1\le n \le 10^5,1\le k \le \fracn(n-1)2\)
正解算法
易知:一个区间的子区间的权值一定不超过这个区间的权值
二分答案\(rez\),利用尺取法计算出右端点不同时权值不超过\(rez\)的最大区间,从而计算出\(rez\)的排名\(rank\)
将\(rank\)与\(k\)比较,则可得到\(rez\)与\(ans\)的大小关系
金牌赛事
题目描述
有\(n\)条连成一线的道路,每条道路都有一个修缮花费\(C_i\),一开始所有的道路都是坏的
还有\(m\)场比赛,每场比赛需要使用\([L_i,R_i]\)之间的道路,举行后可以获得\(W_i\)的收益
你需要选择举行一部分比赛,并修复一部分道路,使得\((\sum W_i-\sum C_i)\)最大
限制范围
\(Time:2000ms\quad Space:128MB\)
\(1\le n,m\le 2\times 10^5,0\le C_i\le 10^9,1\le W_i\le 10^9,1\le L_i\le R_i \le n\)
正解算法
定义\(ext(i,j)\)为考虑到第\(j\)条公路时刚好修了第\(i\)到第\(j\)条公路时的最大总收益,\(imp(i)\)为不修第\(i\)条公路时的最大总收益,则有以下转移式:
\[
imp(j+1)=\max(\max_i=1^j ext(i),imp(j))\exp(i,i)=imp(i)-C_i+W_i,i\exp(i,j)=exp(i,j-1)-C_j+\sum_k=i^j W_k,j
\]
利用线段树维护\(exp\)即可得解
楼梯数字
题目描述
定义楼梯数字为除个位外,每一位都不超过下一位的数,求有多少个位数恰好为\(n\)的楼梯数字为\(k\)的倍数,要求输出\(ans\ mod\ (10^9+7)\)
限制范围
\(Time:3000ms\quad Space:128MB\)
\(1\le n \le 10^18,2\le k\le 500\)
正解算法
每个楼梯数字均可以表示为\(\sum_i=1^9\frac10^C_i-19,C_i\le C_i+1\)
首先求出不同\((\frac10^a-19\ mod\ k)\)下\(a\)的个数,然后通过背包的方式求出模\(k\)的结果不同时楼梯数字的个数
注意,由于\(\frac10^n-19\)至少要选一次,所以要事先计算好它的贡献
路径并计数
题目描述
给定一棵有\(n\)个点的树,树上的每条边都有长度\(l_s\),以及\(m\)条路径\((u_i,v_i)\)
设\(f(i,j)=\sum_s\in\bigcap_t=i^j(u_t,v_t)l_s\),求\(\sum_1\le i\le j\le mf(i,j)\)在模\((10^9+7)\)时的取值
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n,m\le 5\times 10^5\)
正解算法
考虑一条边会在多少个\(f(i,j)\)中被计算
若一个点的父边在\(f(i,j)\)中被计算,那么必然有:对所有\([i,j]\)之间的路径,都有刚好一个端点在这个点的子树中,反之亦然
那么对整棵树DP,得到每个点的父边的被包含情况,则可算出答案
2019年8月19日星期一
梦境
题目描述
给定\(n\)个数\(\X_i\\)与\(m\)个闭区间\(\L_i,R_i\\),需要将数与区间之间两两配对,使得每个配对的区间都包含了它所配对的数,求最大匹配数
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n,m\le 2\times 10^5,1\le L_i\le R_i\le 10^9,1\le X_i\le 10^6\)
正解算法
从小到大枚举每个数,贪心地将其与包含它的、右端点最小的区间匹配
玩具
题目描述
给出一棵有\(n\)个点的有根树,根为编号为\(1\)的点,除\(1\)号点外每个点的父亲的编号均小于自身的编号,求这棵树的最大深度的期望在模\(p\)下的取值
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n\le 200,p\le 10^9+7,p\in \mathbbP\)
正解算法
设\(sol(i,j)\)为含\(i\)个点,且最大深度不超过\(j\)的方案数,则有:
\[
sol(i,u)=[i=1],u\le 0\sol(1,j)=sol(0,j)=1\sol(i,j)=\sum_k=1^i C_i-2^k-1sol(k,j-1)sol(i-k,j)
\]
可以得到:\(ans=\frac1(n-1)!\sum_k=0^n-1(sol(n,k)-sol(n,k-1))\)
飘雪圣域
题目描述
给定一棵有\(n\)个点的树,有\(q\)次询问,均形如:求编号在\([L_i,R_i]\)之中的点所组成的极大独立集的个数
限制范围
\(1\le n,q\le 2\times 10^5,1\le L_i\le R_i \le n\)
正解算法
易知:最大独立集个数=点数-边数
因此,用主席树(在线)或树状数组(离线)计算出连接两个编号在\([L,R]\)的点的边的数量,然后就可以快速求解了
2019年8月20日星期二
mine
题目描述
给出一个一维扫雷游戏的残局,长度为\(n\),可能为如下\(5\)种字符:
0?1?2
代表这个格子里没有地雷,且相邻的格子里有\(0/1/2\)个地雷*
代表这个格子里有一个地雷?
代表未知格,其中可能为* 1?2?3
中的任何一种
求将所有?
替换为* 1 2 3
后有多少种可能的合法局面
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n\le 10^6\)
正解算法
以“前一个位置的状态”对“方案数”进行DP
water
题目描述
有一块土地被分为\(n\times m\)个正方形小块,这些小块高低不平,每一小块都有自己的高度\(H_i,j\),土地外围为无限大、高度为\(0\)的平地
求在四连通时,每个小块的最大积水高度
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n,m \le 300,|H_i,j|\le 10^9\)
正解算法
推导可知,一个小块积水后的最大总高度为从这个小块离开这个土地的所有 路径最高小块 的最小值
由上面结论得,若对原图的小块之间两两连一条权值为\(\max(较高小块的高度,0)\)的边,那么原问题可以转化为最大瓶颈边问题,可以使用最小生成树算法解决
gcd
题目描述
有\(n\)个正整数\(\X_i\\),初始状态均为未选择
有\(m\)个操作,每个操作给定一个编号\(p\),表示将\(X_p\)的选取状态取反
每次操作后,你需要求出选取的数中有多少互质的无序数对
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n,m \le 2\times 10^5,X_i \le 5 \times 10^5,1\le p \le n\)
正解算法
记录\(f(p)=|\i\mid p|X_i且X_i被选择\|\),可以得出下式:
\[
ans=\sum_i=1^\max\X_i\\mu(i)\fracf(i)(f(i)-1)2
\]
动态维护即可
2019年8月21日星期三
Matrix
题目描述
给定一个\(n\)行\(m\)列的\(01\)矩阵,求在若干次交换任意两行的操作后,最大的全\(1\)子矩阵
限制范围
\(Time:1000ms\quad Space:64MB\)
\(1\le n,m \le 1000\)
正解算法
记录每个位置向右延伸的全\(1\)段的最大长度
枚举这个子矩阵的左端点与行数,可以通过预处理的数据得出最远右端点,从而更新答案
Present
题目描述
有\(n\)种物品,每种物品的体积为\(P_i\),数量均为无数件,还有\(m\)个要求,每个要求形如凑出体积和刚好为\(A_i\)的物品集合,问最多能够满足多少个要求
限制范围
\(Time:1000ms\quad Space:64MB\)
\(n\le 500,m\le 3\times 10^5,0<P_i\le 10^4,0\le A_i \le 4\times 10^7\)
正解算法
设所有物品中体积最小为\(S\),用类似背包问题的方式计算出不同\((A_i\ mod\ S)\)下可以得到的最小\(A_i\),记为\(B_A_i\ mod\ S\)
对每个要求\(A_i\),只要询问是否有\(B_A_i\ mod\ S\le A_i\)即可
Mahjong
题目描述
给出一副有\(13\)张牌的牌型,求加上哪些牌后可以胡牌,胡牌牌型如下:
- \(4\)个“面子”(\(3\)张相同的牌或\(3\)张同色且数字连续的牌)+\(1\)个“对子”(\(2\)张相同的牌)
- \(7\)个不同的“对子”
- 由“一万”“九万”“一筒”“九筒”“一条”“九条”“东”“南”“西”“北”“白板”“发财”“红中”这\(13\)张牌加上其中任意一张牌
注意,每种牌最多存在四张
限制范围
\(Time:1000ms\quad Space:64MB\)
多组数据,\(T\approx 10^4\)
\(Special\ Judge\),无需考虑输出顺序
正解算法
枚举加入的牌,暴力找出是否有合法的出牌方案
2019年8月22日星期四
嘟嘟噜
题目描述
计算约瑟夫问题中幸存者的编号(从\(1\)开始计数)
其中总人数为\(n\),每\(k\)次计数杀死一人
限制范围
\(Time:2000ms\quad Space:512MB\)
多组数据,\(1\le T \le 20\)
编译选项:-O2?-Wl,--stack=100000000
\(1\le n \le 10^9,1\le k \le 10^5\)
正解算法
当\(n<k\)时,我们可以通过\((n-1,k)\)的结果计算出\((n,k)\)的结果,只需要将这次死的人的后面一位重新编号为\(1\),变为\((n-1,k)\)的约瑟夫问题,再倒推出原来的幸存者编号便可
当\(n\ge k\)时,可以快速计算出在计数完一圈前所有死去的人的编号,再重新编号,变为\((n-\left\lfloor\fracnk\right\rfloor,k)\)的约瑟夫问题,计算完子问题后倒推便可
天才绅士少女助手克里斯蒂娜
题目描述
有\(n\)个向量,要求维护\(m\)个操作,每个操作可能为下面中的一种:
- 将向量\(\mathbfv_i\)更改为\((x,y)\)
- 给定\(l,r\),求出\(\sum_l\le i<j\le r|\mathbfv_i\times\mathbfv_j|^2\qquad(mod\ 20170927)\)的值
限制范围
\(Time:2000ms\quad Space:512MB\)
编译选项:-O2
\(1\le n,m\le 10^6,0\le x,y <20170927,1\le l< r \le n\)
正解算法
数学推导可知:
\[
\beginalign
&\sum_l\le i<j\le r|\mathbfv_i\times\mathbfv_j|^2\=&\sum_l\le i<j\le r(x_iy_j-x_jy_i)^2\=&\left(\sum_k=l^rx_i^2\right)\left(\sum_k=l^ry_i^2\right)-\left(\sum_k=l^rx_iy_i\right)^2
\endalign
\]
用树状数组维护三个关键数据即可
凤凰院凶真
题目描述
给定一个长度为\(n\)的序列\(A\)与一个长度为\(m\)的序列\(B\),求这两个序列的最长严格上升子序列
限制范围
\(Time:2000ms\quad Space:512MB\)
\(1\le n,m\le 5000\)
正解算法
考虑DP,设\(sol(i,j)\)表示考虑到\(A_i\)与\(B_j\),且答案的最后一个数为\(B_j\)时的答案
当\(A_i=B_j\)时,显然有\(sol(i,j)=\max_k<j,B_k<B_j\sol(i-1,k)\+1\),否则\(sol(i,j)=sol(i-1,j)\)
于是只要从小到大枚举\(j\),维护\(\max_k<j,B_k<A_i\sol(i-1,k)\\),直接转移即可
2019年8月26日星期一
树状数组
题目描述
设\(f(l,r)\)为在树状数组中与\([l,r]\)的区间和的取值相关的位置个数
现在给定\(n\),要求求出下式的值:
\[
\sum_l=1^n\sum_r=l^n f(l,r)\qquad(mod\ 10^9+7)
\]
限制范围
\(Time:2000ms\quad Space:512MB\)
多组数据,\(1\le T \le 10^4\)
\(1\le n \le 10^18\)
正解算法
数学推导可知,\(f(l,r)=count_1(l-1)+count_1(r)-count_1(lcp(l-1,r))\)
从而可推出:
\[
\beginalign
&\sum_l=1^n\sum_r=l^r f(l,r)\=&\sum_l=1^n\sum_r=l^n (count_1(l-1)+count_1(r)-count_1(lcp(l-1,r)))\=&\sum_l=1^n(count_1(l-1)\cdot (n-l+1))+\sum_r=1^n(count_1(r)\cdot r)+\sum_l=1^n\sum_r=l^n count_1(lcp(l-1,r))\=&(n+1)\sum_i=1^n count_1(i)+\sum_l=1^n\sum_r=l^n count_1(lcp(l-1,r))
\endalign
\]
由于\(\sum_i=1^n count_1(i)\)比较容易计算,也就是说,只要快速计算出\(\sum_l=1^n\sum_r=l^n count_1(lcp(l-1,r))\)的值即可计算出答案
我们可以设这样一个数位DP:以“正在考虑的数位\(i\)”“\(count_1(lcp(l-1,r))\)”“\(l,r,n\)的大小关系”向“方案数”做DP
雇佣妹抖
题目描述
有一条有\(n\)个点的链,每个点上都有点权\(A_i\),要求维护\(q\)次两种操作:
- 修改单个点的点权
- 求点权大于给定值的点所组成的极大连通块的数量
限制范围
\(Time:2000ms\quad Space:512MB\)
\(1\le n,q\le 2\times 10^5,任意时刻1\le A_i\le 10^9\)
正解算法
可以发现,\(ans_d=|\x\mid x\in V\ and\ A_x\ge d\|-|\(x,y)\mid (x,y)\in E\ and\ \min(A_x,A_y)\ge d\|\)
也就是说,我们只要维护每个点的点权与每条边端点的较小点权即可求出答案
维护操作在线(平衡树解决)或离线(离散化+树状数组)均可
建造
题目描述
给定正整数\(n,l\),求有多少正整数序列对\((H_i,X_i)\),满足:
- \(H_i\)为\(1\sim n\)的一个排列
- \(X_i\le l\),且\(X_i\)互不相同
- \(\forall i,j\quad|X_i-X_j|\ge\max(H_i,H_j)\)
限制范围
\(Time:3000ms\quad Space:512MB\)
给定模数,满足\(10^8\le m \le 10^9\),且\(m\in \mathbbP\)
\(1\le n \le 100,1\le l \le 10^5\)
正解算法
假定\(X_i\)为升序排列(对原问题无影响)
易知,只要相邻的两个下标满足条件,那么所有的下标都满足条件,反之亦然
若\(H_i\)均已给定,那么通过插板法可知,此时\(X_i\)有\(C^n_l+n-1+\sum\max(H_i,H_i+1)\)种方案
也就是说,我们只要计算不同\(\sum\max(H_i,H_i+1)\)时\(H_i\)的方案数,即可计算答案
以“已经计算\(1\sim i\)的排列”“\(\sum\max(H_i,H_i+1)\)”“还有\(k\)个位置要加入\((i+1)\sim n\)的数”对方案数DP
2019年8月27日星期二
异或统计
题目描述
给定一个长度为\(n\)的非负整数序列\(A\),求:
\[
\sum_1\le i<j<k\le n(A_i\oplus A_j)(A_j\oplus A_k)(A_k\oplus A_i)\qquad(mod\ 998244353)
\]
限制范围
\(Time:3000ms\quad Space:512MB\)
\(1\le n\le 10^5,0\le A_i<2^31\)
集合统计
题目描述
给定正整数\(n,m,k\),考虑所有大小为\(k\)的正整数可重集合\(\A_i\\),使得\(\sum^k_i=1A_i=n\),定义这样的一个可重集合的权值为\(\sum^k_i=1A^m_i\),求所有满足条件的可重集合的权值之和模\((10^9+7)\)的余数
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n,m\le 5000,1\le k \le n\)
异或统计2
题目描述
给定\(n\)和\(k\),你需要统计满足以下两个条件的非负整数数组\(A[1,2,\cdots,n]\)的个数:
- \(\max_i=1^k A[i]\le k\)
- \(\bigotimes_i=1^k A[i]>0\)
由于答案可能过大,所以你需要将答案对\(998244353\)取模
限制范围
\(1\le n,k \le 10^9\)
2019年8月28日星期三
强军战歌
题目描述
给定一个有\(n\)个数的序列\(A\),如果\(A\)不是严格不下降序列,则需要在其中选择一个数删掉, 不断重复这个操作,直到\(A\)为严格不下降序列,求有多少种不同的删数方案
注意:删掉的数的集合相同,但是删数的顺序不同,视作不同的删数方案。
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n,A_i\le 2000\)
正解算法
首先不考虑删数顺序,枚举最后剩下的序列\(B\)
若\(|B|=k\),那么此时的删数方案为\((n-k)!\)
若一种方案不合法,那么这个方案一定是将一个长度为\((k+1)\)的序列删除一个数得到的
反过来,一个长度为\(k\)的方案(无论合不合法)一定能构造出\(k\)个不合法的方案
也就是说,只要统计出不同长度下的严格不下降序列总数,就可以统计出有多少种合法方案数
当那一天来临
题目描述
有一条含\(n\)个点的链,所有点从左往右被依次编号为$1\sim \(n,每个点都有一个点值\)w_i$
在这条链上有两个人\(A\)与\(B\),分别位于\(1\)号点与\(n\)号点
现在这两个人相向而行,需要走到一个点相会。行走方式为:两人交替选择让自己走一步,或让对方走一步
若一个人的收益为他所走过的所有点的权值,那么在两人都选取最优策略时,问\(A\)与\(B\)中哪个最后的收益较大
限制范围
\(Time:1000ms\quad Space:512MB\)
多组数据,\(1\le T\le 10\)
\(1\le n,w_i\le 10^4\)
正解算法
先预处理出在任意点相遇时的获胜者
当\(n\)为偶数时,若中间两个点中有先手必胜的点,那么先手能够让这个点在操作后处于两人中间,然后与对方对称地操作即可;若中间无先手必胜点,但有平局点,同理可达成平局;若仅有后手必胜点,则后手可用类似方法获胜
当\(n\)为奇数时,先手无论进行什么操作,都会成为\(N\)为偶数的情况中的后手,那么只要枚举第一步操作即可算出全局结果
假如战争今天爆发
题目描述
有\(n\)件物品,每件物品都要被三台机器依次加工,每件物品在三台机器上加工所需时间分别为\(A_i,B_i,C_i\)
显然每台机器在同一时刻只能价格一件物品
求让所有物品加工完毕所需要的最少时间
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n\le 10^5,0<A_i,B_i,C_i<10^6\)
正解算法
推导可知,物品\(u\)在物品\(v\)前面的充要条件为\(A_u+C_v+\max(B_u+C_u,A_v+B_v)<A_v+C_u+\max(B_v+C_v,A_u+B_u)\)
按上式排序后模拟算出答案即可
2019年8月29日星期四
Last mile of the way
题目描述
给定一棵有\(n\)个点的有根树,其中每个点都有体积\(S_i\)与权值\(A_i\)
接下来有\(Q\)个询问,形如\((x,t)\),表示在\(x\)为根的子树的所有点中不重复地选取一些点,使得体积之和不超过\(t\),求出此时的最大权值和
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n,t,S_i\le 5000,A_i\le10^6,Q\le 10^5\)
正解算法
先考虑一条链的情况,我们可以按照01背包的方式计算出不同\((x,T)\)时的答案
再将给定的树给长链剖分,在每条长链上按上述方法维护,对轻边暴力维护即可
Reason For Living
题目描述
给定一个有\(n\)个点与\(m\)条边的无向图,需要进行若干次操作,每次操作形如:选择一棵未被全部染色的极大生成树,将上面所有未被染色的边染色
你需要找出一组将所有边全部染色的可行解,且对每一条边均求出它是在第几次操作中被染色的
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n,m\le 10^6\)
正解算法
World Of Our Own
给定一个长度为\(n\)的数组\(A[1,2,\cdots,n]\)
需要构造出\(n\)个新数列,满足\(K_1,i=A[i](1\le i\le n),K_u,v=K_u-1,v\oplus K_u-1,v+1(1\le v \le u,u \ge 2)\)
求\(K_i,1(i=1,2,\cdots,n)\)
限制范围
\(Time:1000ms\quad Space:512MB\)
\(A[i]\)随机,随机数生成函数为:\(A[i]=a,A[i+1]=(A[i]^2+b\cdot A[i]+c)\ mods\ d\)
输出压缩,输出结果为\(\bigoplus_i=1^n(K_i,1\times i)\)
\(n\le 8\times 10^6,A[i]<10^9\)
正解算法
通过数学推导可知,\(C_n^m=2k+1\iff bitand(n,m)=m\)
也就是说,我们有\(K_i,1=\bigoplus_bitand(i,i-j)=i-jA[j]\)
然后对原数列进行\(FWT\)(不需要\(IFWT\))便可得到\(K_i,1\)
2019年8月30日星期五
Graph
题目描述
给定一个有\(n\)个点\(m\)条边的无向图,保证无重边自环,但不保证连通
你需要将这个图分割为多条没有相同边的,长度为\(2\)的链,输出使分割数最大的分割方案
限制范围
\(Time:2000ms\quad Space:512MB\)
\(n\le 10^5,m\le 2\times 10^5\)
正解算法
首先可以证得:一个连通块的最大分割数等于其边数的一半(向下取整)
然后对原图进行DFS,每到一个DFS树上的叶节点,就将这个点的所有非父边全部两两配对(如果非父边有奇数条,则要把剩下的非父边与父边配对)
Permutation
题目描述
给定一个长度为\(n\)的排列\(P\)与一个正整数\(k\)
你可以进行这样的操作:对于两个满足\(|i-j|\ge k\)且\(|P_i-P_j|=1\)的\(i,j\),交换\(P_i,P_j\)
要求输出进行若干次上述操作后,字典序最小的\(P\)
限制范围
\(Time:2000ms\quad Space:512MB\)
\(1\le k\le n \le 5\times 10^5\)
正解算法
首先构造一个新排列\(Q\),满足\(P_Q_i=i\),原操作则等价于交换\(Q\)中相邻两个相差超过\(k\)的值
易证得当\(Q\)取字典序最小时,对应的\(P\)也为字典序最小时的合法排列
然后将每个\(i\)都向\(j_1=\min\u\in(i,n]|Q_i-k<Q_u<Q_i\\)与\(j_2=\min\v\in(i,n]|Q_i<Q_v<Q_i+k\\)连有向边,这样构造出来的有向图的最小字典序括扑排序即为合法的\(Q_\min\)
构造出\(Q_\min\)后,即可构造出\(P_\min\)
Tree
题目描述
给定一棵有\(n\)个点的树,树带边权,试求一个排列\(P\),使下式的值最大
$
\sum_i=1^n-1maxflow(P_i,P_i+1)
$
其中\(maxflow(s,t)\)代表从\(s\)到\(t\)的最大流,即\(s\)到\(t\)的唯一简单路径上最小的边权
限制范围
\(Time:2000ms\quad Space:512MB\)
\(n\le 10^5\)
正解算法
答案为所有边的边权和,即\(ans=\sum w\)
可行性证明:
? 我们考虑直接构造这个可行解
- 按边权从大到小枚举边,每次将边的端点所在的答案序列按字符串连接的方式连接
- 易知按照这样得出的答案序列的权值和一定是\(\sum w\)
- 注意:此时考虑这\(n\)个点所组成\((n-1)\)对点对,它们的瓶颈边恰好包含了所有边恰好一次
最优性证明:
- 考虑最小边两端的子树,可以知道:只有跨过最小边刚好一次的序列比跨过最小边超过一次的序列更优
- 递归考虑两端子树,发现对任意边为瓶颈边的情况都刚好出现一次时,答案是最优的,因此结论成立
2019年9月7日星期六
spongebob
题目描述
给定\(n,a_i,b_i\),要求求出\(\min_x\in \mathbb R\sum_i=1^n |a_ix+b_i|\)
限制范围
\(Time: 1000ms\quad Space:512MB\)
编译选项:-lm -O2 -std=c++11
\(Special\ Judge\),答案与正确答案的差的容许值为\(10^-3\)
\(n\le 3\times 10^5,|a_i|\le 10^4,|b_i|\le 10^6\)
正解算法
方法一
由于\(f(x)=\sum_i=1^n |a_ix+b_i|\)关于\(x\)为单峰函数,所以可以使用三分法寻找最值,\(f(x)\)的值暴力计算即可
方法二
可以发现,当\(f(x)=\sum_i=1^n |a_ix+b_i|\)取最小值时,必然有\(\exists i,a_ix+b_i=0\),那么只要按\(-\fracb_ia_i\)从小到大枚举\(i\),并且动态维护\(f(x)\),即可算出\(\min f(x)\)
patrick
题目描述
给出一个长度为\(n\)的链,编号\(1\sim n\),每个点有点权\(a_i\),要求维护\(m\)个操作,每个操作有下列两种可能形式:
- 将\(a_i\)修改为\(x\)
- 求编号在\(\i\mid a_i\ge y\\)的点所组成的极大连通块的数量
限制范围
\(Time: 1000ms\quad Space:512MB\)
编译选项:-lm -O2 -std=c++11
强制在线,读入数据实际为\(u\oplus lastans\)
\(n,m,x,y,a_i\le 5\times 10^5\)
正解算法
由于有\(极大连通块的数量=点数-边数\),那么只要维护\(|\i\mid a_i\ge y\|\)与\(|\i\mid \min(a_i,a_i+1)\ge y\|\)即可,仅需树状数组(因为\(a_i,x\)的范围较小)
eugene
题目描述
有\(n\)个员工与\(m\)份调查问卷,每份调查问卷均形如\((a_i,b_i,c_i)\),代表在员工\(a_i\)与员工\(b_i\)中选取一人,给他加上\(c_i\)分,并给另外一人扣除\(c_i\)分(分数可以为负)
求问是否存在一种选择方式,使得每个人最后的总得分的绝对值不超过\(1\)
注意,这些调查问卷满足如下条件:
- \(a_i\ne b_i\)
- \(c_i\in\1,2\\)
- 对于员工\(j\),若\(\exists i,a_i=j\or b_i=j\),那么有\((\sum_a_i=j\or b_i=jc_i)\)为奇数
要求输出方案,如果没有,需输出-1
限制范围
\(Time: 2000ms\quad Space:512MB\)
编译选项:-lm -O2 -std=c++11
\(2\le n\le 10^6,m\le 10^6,0\le a_i,b_i<n,c_i\in\1,2\,a_i\ne b_i\)
正解算法
首先将\(c_i\)相同的重边两两配对,加分与减分抵消,使得最后剩余不超过\(n(n-1)\)条边
然后对于\((u,mid,s)(mid,v,s)\),我们可以将其简化为\((u,v,s)\),然后通过这条边的取值可倒推出原来两条边的取值
经过上面的简化,\(\i\mid c_i=1\\)的边与\(\i\mid c_i=2\\)的边分别会组成一个二分图,而原图一定为一个或多个\(c_i=1\)与\(c_i=2\)的边交替的链或环的集合,任意定向即可
注意,如果简化后的图无解,那么原图一定也无解
2019年9月8日星期日
tom
题目描述
给定一棵有\(n\)个点的树,要求将这些点编号为\([1,n]\)之间在正整数,使得\(\forall l\in[1,a],r\in[a+1,n]\quad[l,r]的点为一个连通块\)
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-lm?-O2?-std=C++11
\(Special\ Judge\),输出任意一组解即可
\(1\le a < n \le 10^5\)
正解算法
首先用DFS找出是否存在两边子树大小分别为\(a\)与\((n-a)\)
如果有,那么原问题可转化为两个树上括扑排序问题,用任意方式均可(如DFS序)
如果没有,那么原问题无解
jerry
题目描述
给定一个仅有\(+,-\)两种运算的算式,算式中的每个数均为非负整数,要求在这个式子中加入若干括号对,使得算式的结果最大
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-lm?-O2?-std=C++11
\(2 \le n \le 10^5\)
多组数据,\(\sum n \le 2 \times 10 ^ 5\)
正解算法
设\(sol(i)\)为以第\(i\)个符号开始的后缀可以得到的最大结果
考虑第\(i\)与第\((i+1)\)个数
- 若为\(\cdots + a_i + \cdots\),那么有\(sol(i)=sol(i+1)+a_i\)
- 若为\(\cdots - a_i + a_i+1 \cdots\),那么可以不加括号,有\(sol(i)=sol(i+1)-a_i\)
- 若为\(\cdots - a_i - a_i+1 \cdots\),那么可能为\(\cdots - a_i - a_i+1\cdots\)或\(\cdots - (a_i - a_i+1)\cdots\),即\(sol(i)=\max(sol(i+1)-a_i,sol(i+2)+a_i+1-a_i)\)
DP即可得解
speike
题目描述
在\(x=0\)与\(x=t\)之间有\(n\)个矩形,所有矩形的边均平行于坐标轴,且两两互不相交(这里的矩形不包含边界)
现在有一个人要从\((0,0)\)走到\((t,0)\),但是必须平行于坐标轴移动,求在不碰到矩形的要走的最小总长度
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-lm?-O2?-std=C++11
\(0 < t \le 10^8,0\le n \le 10^5\)
\(若矩形顶点为(a,b),(a,d),(b,c),(b,d),有0\le a < c \le t,-10^8 \le b < d \le 10^8\)
正解算法
2019年9月10日星期二
乌合之众
题目描述
给定一个\(n\times n\)的矩阵\(S\),要求求出\(\sum_T\subseteq S\bigwedge_x\in Tx\)和\(\sum_T\subseteq S\bigoplus_x\in Tx\)
限制范围
\(Time:3000ms\quad Space:256MB\)
编译选项:-O2 -lm -Wl,–stack=256000000
\(n\le10^3,0\le x<2^31\)
正解算法
首先按照二进制位将每个数分成多个\(x\in\0,1\\)的问题
对于\(\sum_T\subseteq S\bigwedge_x\in Tx\),我们可以发现,这个式子的值为全\(1\)子矩阵的数量
对于\(\sum_T\subseteq S\bigoplus_x\in Tx\),我们可以得到\(\sum_T\subseteq S\bigoplus_x\in Tx=\sum_T\subseteq S\bigvee_x\in Tx-\sum_T\subseteq S\bigwedge_x\in Tx\),也就是说,答案为全\(1\)子矩阵的数量与含\(1\)子矩阵的数量的差
圣战
题目描述
给定一个有\(n\)个点\(m\)条边的无向图,问如果只删除一条边,从而构成一个二分图,这样的方案有多少种,并输出所有的方案
限制范围
\(Time:1000ms\quad Space:256MB\)
编译选项:-O2 -lm -Wl,–stack=256000000
\(n,m\le 5\times 10^5\)
正解算法
可以发现,所有可以删去的边均在所有奇环的交上
然后利用DFS找环,
- 如果找到的环为奇环,直接加入答案即可
- 如果找到的环为偶环,那么记录这个偶环。当发现这个偶环包含了一个奇环时,说明这个奇环的互补环也是一个奇环,那么再加入这个互补的奇环
花火之声不闻于耳
题目描述
给出一个长度为\(n\)的正整数序列\(A\),要求进行\(m\)次操作,可能为如下两种中的一种:
- 修改操作:\(a_i\leftarrow a_ix,i\in[l,r]\)
- 询问操作:询问\(\varphi (\prod_i=l^ra_i)\ mod\ 998244353\)
限制范围
\(Time:2000ms\quad Space:256MB\)
编译选项:-O2 -lm -Wl,–stack=256000000
\(n,m\le 4\times 10^5,x,a_i\le 300\)
正解算法
易知:\(\varphi (\prod_i=l^ra_i)=(\prod_i=l^ra_i)(\prod_\exists i\in[l,r],p|a_i(1-p^-1))\)
那么我们只要用线段树维护\(\prod_i=l^ra_i\)以及\(\forall p\exists i\in[l,r],p|a_i\)(或运算线段树)即可
2019年9月12日星期四
树链剖分
题目描述
给定一棵有根树,其根为\(1\)号点
一开始,只有\(1\)号点被标记
现在需要维护两种操作,共\(m\)个:
- 将\(i\)号点打上标记
- 求出距离\(i\)最近的\(i\)的祖先\(j\),使得\(j\)被标记
限制范围
\(Time: 3500ms\quad Space:512MB\)
编译选项:-lm -Wl,–stack=256000000
\(n\le 10^6,m\le 5\times 10^6\)
正解算法
方法一
用DFS序维护区间最小值(线段树维护即可)
方法二
倒序处理所有操作,将所有答案相同的节点合并为一个集合,每次撤销一个标记操作等价于将两个集合合并,查询操作只要找到集合的代表元素即可(如果答案节点就是集合的代表元素)
天气之子
题目描述
有\(n\)个人依次坐在一排座位中,他们坐座位的方式是这样的:
- 第\(1\)个人坐在第\(1\)个位置上
- 后面的所有人都会坐在一个空位上,使得其与最近的已经坐下的人尽量远
- 如果有多个合法位置,它们会坐在任意一个可能的位置上
求使得任意两个人的位置均不相邻的最少座位数
限制范围
\(Time: 1000ms\quad Space:512MB\)
编译选项:-lm -Wl,–stack=256000000
\(n\le 10^1000\)
正解算法
打表可知:
\[
f(n)=
\left\\beginarray\1\quad n=1\3\quad n=2\n+2^\lfloor\log_2(n-2)\rfloor+1\quad n\ge 3
\endarray\right.
\]
层层染君色
题目描述
给定一棵含\(n\)个节点的、以\(1\)为根的有根树,其边有边权
记\(dis(a)\)为树根到\(a\)的距离,\(f(x)=\sum_i=1^xi^k\)
每个节点可能为黑色或白色,一棵树每个节点均为白色
现在有\(m\)个操作,每个操作可能为下列两种中的一种:
- 将节点\(x\)染为黑色
- 求\(\sum_i\ is\ blackf(dist(lca(i,x)))\quad mod\ 998244353\)
限制范围
\(Time: 2000ms\quad Space:512MB\)
编译选项:-lm -Wl,–stack=256000000
\(n,m\le 10^5,dist(i)\le 10^7,k<998244353\)
正解算法
预处理出所有的\(f(dist(x))\),并对原树进行树链剖分
对每个点维护子树中黑点的个数,对每条重链维护它对链底的答案贡献
当维护询问操作需要经过轻边时,暴力计算轻边边顶的贡献即可
2019年9月13日星期五
achen
题目描述
有\(n\)个亭子,第\(i\)个亭子与第\((i-2),(i-1),(i+1),(i+2)\)个亭子有双向连廊
现在要从第\(a\)个亭子走到第\(b\)个亭子,要求所有亭子都必须到达刚好一次,问行走的方案数,要求对\(998244353\)取模
限制范围
\(Time: 1000ms\ Space:64MB\)
编译选项:-lm
多组数据,\(T\le10^5\)
\(1<n\le 10^6,1\le a,b\le n,a\ne b\)
正解算法
首先考虑\([1,a-1](a>1)\)的行走方式,可以发现,这一段的行走方式必须如下:
对\([b+1,n](b<n)\)时同理,所以答案即为\([a+1,b-1]\)时从一个端点走到另一个端点的答案,DP即可求解
注意:当\(a=1\)时,最后求解的区间左端点为\(1\),\(b=n\)时同理
tree
题目描述
有一棵有\(n\)个点的数,每个节点上有一种颜色,一共有\(m\)种不同的颜色,保证每种颜色都至少出现一次
现在需要指定一个树根与一个点集\(T\),使得\(T\)中每种颜色至少出现一次,求\(lca(T)\)的最大深度
限制范围
\(Time: 1000ms\ Space:256MB\)
编译选项:-lm
\(n\le 10^6,m\le 10^5\)
正解算法
易知,必然存在一组最优解,使得\(T\)是原树的一棵子树
首先,我们可以临时指定一个“虚根”,将原树变为有根树,方便计算
通过树上DP的方式,我们可以快速计算出每个点的不同方向上的最远点,即这个点是合法子树的根时,局部最优解的树根
注意到:询问“当根在某一个方向上时,一个点所拥有的子树是否合法”可以转化为一棵子树是否包含所有的颜色(当答案与“虚根”同向时)或一棵反树是否包含所有的颜色(当答案与“虚根”异向时)
对于“一棵子树是否包含所有的颜色”,我们可以用树上差分的方式算出某个点的子树的颜色数:将同种颜色的点按DFS序排序,然后对每个点的颜色数\(+1\),DFS序相邻的两个点的\(lca\)的颜色数\(-1\),这样即可得到所求数据
对于“一棵反树是否包含所有的颜色”,这个问题等价于“一棵子树是否完全包含一种颜色的点”的反问题。由于“一棵子树完全包含一种颜色”等价于“子树的根是 颜色为这种颜色的所有点 的\(lca\)的祖先”,这样也可以通过打标记的方式解决
easy
题目描述
给定一个长度为\(n\)的序列\(a\),求问多少个区间\([l,r](l\le r)\),满足如下条件:
\[
\forall x \in \left[\min_i\in [l,r] a_i,\max_i\in [l,r] a_i\right]\quad \exist i \in [l,r]\quad a_i=x
\]
限制范围
\(Time: 1000ms\ Space:256MB\)
编译选项:-lm
\(n\le 10^5,a_i\le 10^9\)
正解算法
可以发现,区间\([l,r]\)合法等价于下式的成立:
\[
\left(\max_i\in[l,r]a_i\right)- \left(\min_i\in[l,r]a_i\right)-|\i\in[l,r]\mid \exists j\in[l,i],a_i=a_j\|=r-l
\]
对任意位置\(i\),预处理出\(last(i)=\max\j\in[1,i-1]\mid a_i=a_j\\)
由于有\(\left(\max_i\in[l,r]a_i\right)- \left(\min_i\in[l,r]a_i\right)-|\i\in[l,r]\mid last(i)\ge l\|\ge r-l\),因此可以从小到大枚举\(r\),单调栈维护\(\min_i\in[l,r]a_i\)与\(\max_i\in[l,r]a_i\),线段树维护\(\left(\max_i\in[l,r]a_i\right)- \left(\min_i\in[l,r]a_i\right)-|\i\in[l,r]\mid last(i)\ge l\|+l\)关于\(l\)的区间最小值以及最小值出现次数即可
2019年9月16日星期一
doubt
题目描述
给定两个非负整数序列\(A,B\),长度均为\(n\),要求将\(A,B\)重排,使得序列\(\A_i\oplus B_i\\)的字典序最小
限制范围
\(Time:1000ms\quad Space: 256MB\)
编译选项:-lm
\(n\le 2\times 10^5,A_i,B_i< 2^30\)
正解算法
方法一
对\(A\)和\(B\)分别建一棵字典树,对两棵树同时DFS,每次尽量选择同向的树,当到达叶子时,直接将到达的两个叶子所代表的数配对,DFS结束后将答案序列排序即可
方法二
从高往低枚举数位\(p\),并按照第\(p\)位的取值将\(A,B\)分为\((A_L,A_R),(B_L,B_R)\),然后先将\(A_L\)与\(B_L\)合并,\(A_R\)与\(B_R\)合并,若仍然有剩余,那么再将\(A_L\)与\(B_R\)合并,\(A_R\)与\(B_L\)合并即可
block
题目描述
有\(n\)列积木,第\(i\)列的高度为\(H_i\),现在需要对这些积木进行二染色,使得对任意\(2\times 2\)的子矩形中,两种颜色的积木各出现一次,问有多少种不同的合法方案,要求对\((10^9+7)\)取模
限制范围
\(Time:2000ms\quad Space: 128MB\)
编译选项:-lm
\(n\le 10^5,1\le H_i\le 10^9\)
正解算法
首先可以发现,相邻两行只可能有下列两种可能(如下图):
- 对应位置的颜色完全相反
- 对应位置的颜色完全相同,且行内部为两种颜色交错
记第\([l,r]\)列的最左端的颜色为\(p\),最右端的颜色为\(q\),内部颜色是否交替的状态为\(k\),答案为\(dp(l,r,p,q,k)\)
从高到低枚举高度\(H_i\),则需要合并\(dp(l,i-1,p_l,i-1,q_l,i-1,k_l,i-1)\)与\(dp(r,i+1,p_i+1,r,q_i+1,r,k_i+1,r)\),然后将求值区间\([l,i-1],[i+1,r]\)合并为\([l,r]\)
road
题目描述
给定正整数\(n\),问有多少个含\(n\)个点的无向图\(G=(V,E)\),满足如下条件:
- \(|V|=n,|E|=n+1\)
- \(G\)中不含有重边或自环
- \(G\)为点双连通图
限制范围
\(Time:1000ms\quad Space: 256MB\)
编译选项:-lm
\(4 \le n \le 10^9\)
正解算法
由于所有点的度数和为\((2n+2)\),而不能有点的度数为\(1\),因而除了少数点外,大部分的点的度数均为\(2\),讨论这少部分点的可能情况:
- 有一个点的度数为\(4\),整个图是以它为公共点的两个环
- 有两个点度数为\(3\),这两个点直接连接,而且还有两条链连接
- 有两个点度数为\(3\),这两个点未直接连接 ,中间有三条链连接
对于这三种情况,分别计算,可得通项公式为:
$
ans_n=n!\left(\fracn-48+\fracn-34+\frac(n-3)(n-4)4\right)
$
然后分段打表以预处理\(n!\)即可
2019年9月17日星期二
第一题
题目描述
给定正整数\(n,b,k\),要求求出下式的值:
\[
\sum_i=1^nC_i^kb^i\quad mod\ 998244353
\]
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le k\le 5\times 10^5,1\le n\le 10^18,2\le b<998244353\)
正解算法
设\(S_n,k=\sum_i=1^nC_i^kb^i\),那么可得:
\[
\beginalign
S_n,k&=\sum_i=1^nC_i^kb^i\ &=\frac1k!\sum_i=k^ni^\underlinekb^i\ \left( b-1 \right) S_n,k&=\frac1k!\left[ \sum_i=k+1^n+1\left( i-1 \right)^\underlinekb^i-\sum_i=k^ni^\underlinekb^i \right]\ &=\frac1k!\left[ \sum_i=k+1^n\left( \left( i-1 \right) ^\underlinek-i^\underlinek \right)b^i+b^n+1n^\underlinek-b^kk! \right]\ &=C^k_nb^n+1-\left(\fracb\left( k-1 \right) !\sum_i=k-1^n-1i^\underlinek-1b^i\right)\ &=C^k_nb^n+1-bS_n-1,k-1
\endalign
\]
因为\(S_n,0=\fracb(b^n-1)b-1\),因而我们可以递推求解
第二题
题目描述
给定一个有\(n\)个点\(m\)条边的有向图,边的长度均为\(1\),问有多少个有序点对\((a,b)\),满足存在点\(c\)以及路径\((c,a),(c,b)\)(不一定是简单路径),使得\((c,a)\)的长度是\((c,b)\)的两倍
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n,m \le 3000\)
正解算法
枚举中间点\(c\),考虑BFS找出答案
可以发现\((c,a),(c,b)\)的长度和一定是\(3\)的倍数,那么我们可以设这样一个状态\((a,b,\0,1,2\)\),代表两端为\(a,b\),且\((c,a),(c,b)\)的长度和模\(3\)余\(0\ or\ 1\ or\ 2\),然后我们只要进行下列转移即可:
每个\((a,b,\0,1,2\)\)状态最多只需要访问一遍,因此可以优化搜索范围
第三题
题目描述
给定一个\(1\sim n\)的排列,问有多少个区间\([l,r]\),满足\(a_i(i\in [l,r])\)排序后连续
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n\le 3\times 10^5,\forall i\ne j,a_i\ne a_j\)
正解算法
可以发现,\(\forall l,r\quad \max a_i-\min a_i\ge r-l\),且区间合法的充要条件为\(\max a_i-\min a_i= r-l\)
我们可以从小到大枚举\(r\),单调栈维护后缀最大最小值,线段树维护后缀的\(\max a_i-'min a_i+l\)的最小值及最小值出现次数即可
2019年9月18日星期三
优美的字符串
题目描述
给定一个仅含有\(ab\)的字符串\(s\),求在\(ab\rightarrow bba\)的变换下,使得\(s\)中所有\(b\)均为所有\(a\)的前面的最少操作次数
如果无解,要求输出\(-1\),否则输出最少操作次数在模\((10^9+7)\)下的取值
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(|s|\le 10^6\)
正解算法
由于原操作可看成一个\(b\)在跨过一个\(a\)后分裂为两个\(b\)(如下)
那么可以计算出每个\(b\)及其分裂出的\(b\)全部移动到最左端的代价,再求和即可
数字谜题
题目描述
设\(f(x)=x的二进制表示中1的个数\),求满足\(\undersetk\text层\underbracef\text(f\text(\cdots f\text(x\text)\cdots \text))=1,k为满足条件的最小值\)且\(x\in[1,n]\)的\(x\)的解的个数
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(0\le k \le 1000,1\le n< 2^1000\)
正解算法
首先我们可以发现,对题目中的数据范围,有\(f(x)<1000\),因此我们可以枚举\(f(x)\),数位DP求出符合条件的数的个数(只需要对所有\(f(x)\)DP,再查表即可,不需要对每个\(f(x)\)多做一遍DP)
城市规划
题目描述
给定一个有\(n\)个点\(n\)条边的连通无向图,边有长度\(l_i,j\),要求删去一条边,使得得到的图是连通图(一棵树),问删边后树的直径最小为多少
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(3\le n\le 2\times 10^5,1\le l_i.j\le 10^9\)
正解算法
首先可以发现,原图一定是一个基环树,删去的边必须为环上的边
先将基环上的所有子树的直径\(s_i\)与最大深度\(d_i\)预处理出来
然后对下列数据进行DP(已经制定环的起点与方向,连接环两端的边是长度为\(p\)):
- 某个点左侧(包括自身)所有子树的最深节点到起点的最大长度\(pre(i)\)
- 某个点右侧(包括自身)所有子树的最深节点到终点的最大长度\(suff(i)\)
- 某个点左侧(包括自身)所有子树的最大答案\(lef(i)\)
- 某个点右侧(包括自身)所有子树的最大答案\(rig(i)\)
- 某个点到起点的距离\(sumlef(i)\)
- 某个点到终点的距离\(sumrig(i)\)
删除边\((i,j)\)后的结果即为\(\max(lef(i),rig(j),p+pre(i)+suff(j))\)
2019年9月19日星期四
初夏
题目描述
给定一个长度为\(n\)的序列\(A\),同时有\(q\)次询问,每次询问区间\([l,r]\),问\([l,r]\)中是否存在一个严格众数(出现次数大于元素总数的一半),若存在,输出这个众数,否则输出-1
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n,q\le 5\times 10^5,0\le A_i <n\)
正解算法
方法一
考虑瞎搞蒙特卡罗方法
在区间中随机选取一个数,暴力统计出这个数出现的次数(需要进行一定的优化),然后判断这个答案是否合法即可
猜测次数实测\(\ge25\)较优
方法二
主席树维护元素出现次数,询问时尽量往总数较大的分支走,走到最后的叶子节点一定是可能解,再算出是否可行即可
方法三
将所有数二进制拆分,每一位都选取数量较多的数码,这样得出的解为可能解,然后统计是否可行即可
半夏
题目描述
在一条直线上放着\(n\)堆石子,第\(i\)堆中含\(a_i\)颗完全相同的石子
每次可以将相邻两堆石子合并,代价为两堆石子的石子数的和,求将所有石子合并所需要的最小总代价
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n\le 10^5,1\le a_i\le 10^6\)
正解算法
我们需要使用GarsiaWachs算法+平衡树优化
GarsiaWachs算法时这样的:
- 找到满足\(a_k-1\ge a_k+1\)的最大的\(k\)
- 合并\(a_k\)与\(a_k+1\),设新树为\(b\)
- 将\(b\)插入到满足\(t\ge k,a_t+1\ge (a_k\ge a_k+1)\)的最小的\(t\)后面
需要平衡树优化
盛夏
题目描述
给定一个有\(n\)个点\(m\)条边的有向无环图,边有边权,要求选取若干条边,使得从\(1\)号点到\(n\)号点的任意路径上都刚好有一条边被选取,求选取的边的边权和的最小值
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n\le 300,m\le 1000\)
正解算法
首先将不能从\(1\)到达的点与不能到达\(n\)的点排除
然后按照原图建立网络流图建边,同时对每条边建一条容量为\(\infty\)的反向边
这样建立的图的最大流(最小割)即为答案
2019年9月20日星期五
修路
题目描述
给定一个有\(n\)个点\(m\)条边的连通无向图,边的长度均为\(1\),问有多少个无序点对\((u,v)\),满足\((u,v)\notin E\)且加入边\((u,v)\)后\(dist(s,t)\)不变
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(2\le n \le 1000,n-1 \le m \le 2000,s\ne t\)
正解算法
首先对每个点\(x\)算出\(f(x)=dist(s,x),g(x)=dist(x,t)\)
可知\(\forall(u,v)\notin E,(u,v)\in Ans\iff \min(f(u)+g(v),f(v)+g(u))+1\ge dist(s,t)\)
神奇的集合
题目描述
有\(n\)个可重集,一开始所有集合均为空集,现在有\(m\)个操作,每个操作有两种可能:
- 将\(x\)插入到\([l,r]\)的集合中,若某个集合中已经有\(x\),那么不插入元素,而是将这个集合所有已有元素复制
- 查询\([l,r]\)的集合的元素总数,要求对\(998244353\)取模
限制范围
\(Time:5000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(1\le n,m\le 2\times10^5,1\le x\le n\)
正解算法
对每个不同的\(x\)用std::set
维护含\(x\)的集合的区间
线段树维护每个集合的元素个数
缩树游戏
题目描述
给定一棵有\(n\)个点的树,现在要进行如下操作共\((n-1)\)轮:
- 从剩下的边中等概率随机选中一条边\((u,v)\)
- 将\((u,v)\)删去,再新建一个点\(p\),进行:\(\forall (x,u)\in E\or(x,v)\in E,连接(x,p)\)
- 删去\(u,v\)及他们所连的所有边
- 将\(p\)重编号为\(u\)或\(v\)
对每一个编号\(i\),要求求出最后剩下的点的编号为\(i\)的概率
限制范围
\(Time:1000ms\quad Space:512MB\)
编译选项:-O2 -std=c++11 -Wl,--stack=536870912
\(2\le n\le 50\)
正解算法
2019年9月21日星期六
签到题
题目描述
给定一棵有\(n\)个点的无根树,点有点权\(a_i\),现在要求对这棵树DFS(可以从任何点开始),设得到的DFS序为\(d_i\),求\(\sum_i=1^na_id_i\)的最小值
限制范围
\(Time:1000ms\quad Space:256MB\)
\(1\le n,a_i\le 2\times 10^5\)
正解算法
易知,对于任意一个点,其最优的DFS顺序为子树内点权的平均值
首先将原来的无根树转为有根树,用树状DP的方式求出起点为树根时的答案
由于知道一个点的答案,可以快速得到儿子的答案,因此我们可以得出所有点的答案,再暴力枚举即可
简单题
题目描述
给定一个有\(n\)个点\(m\)条边的连通无向图,边有边权\(w_i\),对每条边询问:若改动这条边的边权,使得这条边可能出现在最小生成树上,那么改动后的边权的最大值为多少
限制范围
\(Time:6000ms\quad Space:256MB\)
\(1\le n\le 10^5,n-1\le m\le 10^6,0\le w_i\le 10^9\)
正解算法
首先建立最小生成树
对树边,其答案为所有覆盖了这条边的非树边的边权最小值
对非树边,其答案为其覆盖的所有树边的边权最大值
不难题
题目描述
给定\(k\)个\(1\sim n\)的排列\(a_i,j\),设\(f(l,r)\)为满足\(\forall i\in[1,(r-l)n+1]\exists u\ne v.u,v\in[i,i+n),a_x_u,y_u\ne a_x_v,y_v\)的\((x,y)(l\le x\le r,1\le y\le r)\)的全排列的数量,求\(\sum_i=1^n-1\sum_j=i+1^nf(i,j)\)的值,对\((10^9+7)\)取模
限制范围
\(Time:1000ms\quad Space:256MB\)
\(n,k\le 300\)
排列\(a_i\)均随机产生
正解算法
2019年9月22日星期日
二元组
题目描述
给定正整数\(l,r\)求有多少个二元组\((a,b)\),满足\(l\le a<b\le r\and a,b\in\mathbbN\and a^b>b^a\)
限制范围
\(Time:1000ms\quad Space:256MB\)
多组询问,\(T\le 10^4\)
\(5\le l< r\le 10^6\)
正解算法
由于\(a<b\and a^b\le b^a\)的正整数解仅有\((a,b)=(1,n),(2,3),(2,4)\),因此在题目范围仅需要输出\(\frac(r-l)(r-l+1)2\)即可
三元组
题目描述
给定一个长度为\(n\)的序列\(A\),问有多少个三元组\((x,y,z)(x<y<z)\),使得\(A_x\oplus A_y<A_y\oplus A_z\)
限制范围
\(Time:1000ms\quad Space:256MB\)
多组询问,\(T\le 5\)
\(n\le 5\times 10^4,1\le A_i\le 10^9\)
正解算法
方法一
首先预处理所有区间内第\(i\)位为\(0/1\)的数的个数(存储前缀和)
枚举\(x,z\)第一个不同的位置,然后枚举\(z\),动态维护合法的\((x,y)\)对
可以发现,在这一位上,只可能有\((x,y,z)=(0,0,1),(1,1,0)\),因此可以直接维护
方法二
枚举\(y\),维护一个包含两边的数的Trie树,并记录每一位上满足刚好在第\(i\)位由\(0/1\)变为\(1/0\)的数的个数,从而求解
排序
题目描述
给定一个\(1\sim n\)的排列\(A\),并运行下列程序:
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
if(A[i]>A[j]) swap(A[i],A[j]);
cnt++;
问当\(cnt=k\)时,程序所得到的序列\(A\)
限制范围
\(Time:1000ms\quad Space:256MB\)
\(2\le n\le 10^6,1\le k\le \fracn(n-1)2\)
正解算法
可以看出这是选择排序的代码
首先算出j
进行了几次完整的循环,设为\(s\)
我们可以发现:
- 如果\(i\le s\),那么\(i\)一定在第\(i\)个位置上
- 如果\(i>s\),则需要从大到小考虑
- 如果\(i\)在最左的已经确定的前缀左边,那么排序后一定在这个前缀的后一个位置
- 如果\(i\)在已确定的前缀右边,那么前后的位置一定不变
若处理后\(cnt\)仍然不够,那么再暴力模拟即可
全连
题目描述
有\(n\)个任务,每个任务有一个影响范围\(t_i\)与单位收益\(a_i\),现需要选择一部分任务,设其集合为\(S\),则必须有\(\forall i,j\in S\and i\ne j,|i-j|\ge t_i\),问\(\sum_i\in Sa_it_i\)的最大值
限制范围
\(Time:1000ms\quad Space:256MB\)
\(t_i\le n\le 10^6,a_i\le 10^9\)
正解算法
我们可以发现,若\(i>j\),那么选\(i\)可以选\(j\)的充要条件为\(i\ge j+t_j\)
设\(dp(i)\)为选了\(i\)后\([1,i]\)的最优解,那么可以知道:
\[
\beginalign
dp(i)&=a_it_i+\max_j+t_j\le idp(j)\&=a_it_i+\max\left(\max_j+t_j\le i-1dp(j),\max_j+t_j=idp(j)\right)\&=a_it_i+\max\left(dp(i-1)-a_i-1t_i-1,\max_j+t_j=idp(j)\right)
\endalign
\]
因此我们可以从小到大枚举\(i\),并且动态维护\((i+t_i)\)位置上\(\max_j+t_j=idp(j)\)即可
2019年9月23日星期一
竞选
题目描述
给定一个仅含\(ab\)的字符串\(S\),问要如何将\(b\)变为\(a\),使得对所有子串均有\(count_b-count_a\le k\)
改变第\(i\)个字符的代价为\(2^i\),最后仅需要求出最小总代价即可,对\((10^9+7)\)取模
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le |S|\le 10^6,0\le k\le n\)
正解算法
直接贪心算法
从右往左扫描,若有一个\(b\)是一个非法子串的左端点,那么将这个\(b\)变为\(a\)
树
题目描述
给定一棵有\(n\)个点的无根树,点有点权
还有\(q\)次询问,每次询问与\(x\)距离不超过\(k\)的所有点的点权和
限制范围
\(Time:3000ms\quad Space:512MB\)
\(1\le n\le 2\times 10^6,0\le p_i\le 2^31.1\le q\le 5000,0\le k\le 400\)
正解算法
考虑长链剖分
路径
题目描述
在一个平面中存在\(n\)条射线,其端点为\((x_i,y_i)\),方向为上下左右之一,但未确定
现在问有多少种方案,使得不存在不经过任何一条射线的,从\((-\infty,s)\)到\((\infty,t)\)的路径
要求对\((10^9+7)\)取模
限制范围
\(Time:1000ms\quad Space:512MB\)
\(1\le n\le 50,0\le s,t,x_i,y_i\le 10^9\)
\(\forall i,y_i\ne s\and y_i\ne t\quad \forall i,j,x_i\ne x_j\and y_i\ne y_j\quad s\ne t\)
同时,这个平面中存在 条射线,路径不能和射线相交(包括射线端点)。
射线的端点分别为 ,方向为上下左右之一,尚未确定。
现在土豆想知道,在所有 种情况中,有多少种情况,这个游戏无解。
只需输出答案对 取模的结果。
正解算法
2019年9月24日星期二
循环流
题目描述
给定正整数\(n,a,b\),问是否存在一个有无自环(可以有重边)的含\(n\)个点的流网络,使得这个网络是个弱连通图,且为循环流,仅由刚好\(a\)条容量为\(1\)的边与\(b\)条容量为\(2\)的边组成
限制范围
\(Time:1000ms\quad Space:1024MB\)
编译选项:-O2?-lm
多组数据,\(T\le 127449\)
\(2\le n\le 50,0\le a,b\le 50\)
正解算法
首先我们排除一些不可行解:
- 必须能构成一个带环弱连通图,即\(a+b\ge n\)
- 不能只有一条容量为\(1\)的边,即\(a\ne 1\)
- 当\(n=2\)时,容量为\(1\)的边不能有奇数条,即\(2\mid a\)
- 当\(n=2\and a=0\)时,不能有奇数条容量为\(2\)的边,即\(2\mid b\)
- 当\(n>2\and a+b=n\and ab>0\)时,由于只能成一个环,但环的边不完全相同,不能形成循环流,因此不合法
接下来我们可以发现,剩下的一定都是解:
当\(n=2\)时,我们可以用一条\(2\)边与两条\(1\)边配对,使得两种边的数量都是偶数,再同种边两两配对即可
当\(n>2\)时,我们可以构造这样一组解:
- 若\(ab=0\),那么直接构建一个环,再用裂环或加环的方式补上缺口,有解条件为\(a+b\ge n\)
- 否则可以两种边各自成环(先尽量构造出\(1\)边的环),使得两个环的总点数为\((n+1)\),再用一个公共点连接两个环,剩下的边两两配对即可
整除分块
题目描述
设$f(n)=\min \complement \mathbbN\left a\mid \exists i,\lfloor \fracni \rfloor =a \right \(,求\)\sumi=l^rf(i)\quad mod?998244353$
限制范围
\(Time:2000ms\quad Space:1024MB\)
编译选项:-O2?-lm
多组数据,\(T\le 65536\)
\(l\le r\le 10^36\)
正解算法
打表可知,对\(f(x)\)有:
- \(n^2\le x<n^2+n\)时,\(f(x)=\lfloor\sqrt x\rfloor+\lfloor\frac1 2+\sqrtn^2+n-x\rfloor\)
- \(n^2+n\le x<(n+1)^2\)时,\(f(x)=\lfloor\sqrt x\rfloor+\lfloor1+\sqrtn^2+2n-x\rfloor\)
然后分开计算即可
森林
题目描述
给定一棵树,一开始这棵树仅有一个节点\(1\)
现在每次加入一个节点\((i+1)\),共加入\((n-1)\)次,加入结案的父亲为\(fa_i+1\le i\)
在每次加入节点后,你需要求出进行最多一次操作后树的直径
一次操作定义为:交换两个无祖先关系的子树
限制范围
\(Time:3000ms\quad Space:1024MB\)
编译选项:-O2?-lm
强制在线,\(x'=x\oplus lastans\)
\(1\le n\le 2\times 10^5\)
正解算法
可以发现,答案为直径长+离直径的最大距离-最大距离点不在直径上
由于每次只会加一个叶子节点,因此有如下结论:
- 若原来的直径为\((u,v)\),加入节点为\(x\),那么之后的直径只可能为\((u,v),(u,x),(x,v)\)中的一个
- 离直径的最大距离只增不减
因此我们只要维护直径长与离直径的最大距离即可
2019年9月25日星期三
猜测
题目描述
给定两个长度为\(n\)的序列\(A,B\),满足\(\forall i\ne j,A_i\ne A_j\or B_i\ne B_j\),现在要将这两个序列打乱,使得打乱后的序列仍然满足\(\forall i\ne j,A'_i\ne A'_j\or B'_i\ne B'_j\),问满足\(\exists j,A_j=A'_i\and B_j=B'_i\)的\(i\)的最少数量
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n\le 50,1\le A_i,B_i\le 10^5\)
正解算法
我们先将\(A_i\)与\(B_i\)去重,如下图建立网络流模型,则此模型的最小费用最大流即为答案
星际逃亡
题目描述
在一个三维空间中有\(n\)个点,编号为\(0\sim n-1\),第\(i\)个点一开始的位置在\((x_i,y_i,z_i)\),以\((u_i,v_i,w_i)\)的速度移动
现在要从\(0\)号点移动到\(1\)号点,每次从一个点移动另一个点不需要花费时间,但在一个点上每次驻留的时间不能超过\(s\)
问:在此过程中,在两点之间转移距离的最大值最小为多少?
限制范围
\(Time:2500ms\quad Space:512MB\)
\(2\le n\le 1000,1\le s\le s,-500\le x_i,y_i,z_i,u_i,v_i,w_i\le 500\)
正解算法
首先二分路径的最大长度,这样就可以将问题转化为存在性问题
可以发现,在给定最大路径长度的情况下,两个点直接连通的时间一定是一个连续的区间,那么可以BFS找到不同时间段内哪些点没有与其他点连接(因为只有在这些点上才会受到驻留时间限制的影响),辅助求解
圆圈游戏
题目描述
有\(n\)个互不相交或相切的圆,第\(i\)个圆的圆心为\((x_i,y_i)\),半径为\(r_i\),权值为\(w_i\)
现在要选出一部分圆,使得这些圆两两不包含,求最大权值总和
限制范围
\(Time:1500ms\quad Space:512MB\)
\(1\le n\le 10^5,1\le x_i,y_i,r_i\le 10^8,1\le w_i\le 1000\)
限制范围
如果对所有圆求出包含这个圆的半径最小的圆,那么这个问题就转化为简单的树形DP了
考虑如何求出最小包含圆
我们可以将圆按圆心的\(x\)排序,从每个圆的\((x,y_\max)\)处向上连射线,若与另一个圆的下半弧相交,则两个圆的最小包含圆相同,否则所计算的圆的最小包含圆即为所相交的圆,对是否相交可以用std::set
维护
2019年9月26日星期四
区间第k小
题目描述
给定一个长度为\(n\)的序列\(A\)和一个常数\(w\),满足\(0\le A_i<n\)
现在求\(q\)个询问,均为:问在\([l,r]\)中出现总次数不超过\(w\)的所有数中第\(k\)小的数,若剔除后总数少于\(k\),则输出\(n\)
限制范围
\(Time:3000ms\quad Space: 1024MB\)
编译开启O2
优化
部分数据点强制在线
\(n=q=10^5,w\in\1,10,5000,10^5\\)
正解算法
方法一
考虑二分答案,然后计算不超过猜测值的合法元素的数量
可以发现,当在区间\([l,r]\)中,元素\(x\)仅有最后\(w\)个出现位置的贡献为\(1\),第\((w+1)\)个位置的贡献为\(-w\),剩下的位置的贡献均为\(0\),询问时统计这段区间的所有数的贡献和即为答案
我们可以计算出每一个位置在什么样的询问时贡献分别为\(1,-w,0\),如果询问用二维空间中的点表示,不难发现这些贡献可以各用一个矩形表示,于是转化为二维问题: 支持矩形加和单点求值,这个可以用扫描线和线段树得到
对于离线问题,我们可以用整体二分计算,在线问题则可将将整体二分中使用的线段树持久化即可,实际上就是二维线段树
方法二
如上,但是预处理出部分区间的答案(一般是按照\(l,r\)为\(\lfloor\sqrt n \rfloor\)的倍数处理),然后用在线莫队即可
求和
题目描述
若\(x=\prod_i=1^\inftyp_i^a_i(p_i\in \mathbbP\and\forall i\ne j,p_i\ne p_j)\),定义\(f_k(x)=\prod_i=1^\infty(-1)^a_i[a_i\le k]\),可以发现\(\mu(x)=f_1(x)\)
现给定\(n,d\),求\(\sum_i=1^n\sum_j=1^n\sum_t=1^kf_t(gcd(i,j))\quad mod\ 2^30\)
限制范围
\(Time:3000ms\quad Space: 1024MB\)
编译开启O2
优化
\(0<n\le 10^10,k\in\1,40\\)
正解算法
做数学推导可知:
\[
\beginalign
\sum_i=1^n\sum_j=1^n\sum_t=1^df_t\left( gcd\left( i,j \right) \right)&=\sum_x=1^n\sum_t=1^d\left( f_d\left( x \right) \sum_i=1^\left\lfloor \fracnx \right\rfloor\sum_j=1^\left\lfloor \fracnx \right\rfloor\epsilon \left( gcd\left( i,j \right) \right) \right)\ &=\left( \sum_x=1^n\sum_t=1^df_t\left( x \right) \right) \left( 2t-n \right) & t=\sum_x=1^n\sum_i=1^\left\lfloor \fracnx \right\rfloor\varphi \left( i \right) \ &=\left( \sum_t=1^d\sum_i=1^n\left( \mu \left( i \right) \sum_j=1^\left\lfloor \fracni^t+1 \right\rfloor\lambda \left( i^d+1j \right) \right) \right) \left( 2t-n \right) & \lambda \left( x \right) =f_\infty\left( x \right) \ &=\left( \sum_t=1^d\sum_i=1^\lfloor \sqrt[d+1]n \rfloor\left( \lambda ^t+1\left( i \right) \mu \left( i \right) \varLambda \left( \left\lfloor \fracxi^t+1 \right\rfloor \right) \right) \right)\left( 2t-n \right) \qquad & \varLambda \left( x \right) =\sum_i=1^x\lambda \left( i \right) \\endalign
\]
可以发现\(\sum_t\mid x\lambda(t)=[\exists k\in \mathbbN,k^2=x]\),因此\(\varLambda(x),t\)均可以用杜教筛算出,从而得解
树
题目描述
给定一棵树,树上有\(n\)个点与\((2n-2)\)条有向边,保证当有向边\(u\rightarrow r\)存在时,有向边\(v\rightarrow u\)也存在,且树上任意两个点均可以相互到达
树上每个节点有一个权值,初始为\(0\)
现在有若干条有向简单路径,每条路径都会修改路径上的所有点的权值,修改方式如下:当经过有向边\(u\rightarrow v\)时,若\(u<v\),则\(u,v\)权值均增加\(1\),否则均减少\(1\)
已知最后所有点的权值,求路径的可能方案,要求路径总条数最少,当仍有多组解时,选择字典序最小的
限制范围
\(Time: 2000ms\quad Space:512MB\)
编译开启O2
优化
\(0<n\le 10^6\)
保证存在一组解,使得路径总条数\(m\)满足\(m\le n\)
正解算法
我们可以发现,如果一条路径的起点与另一条路径的终点重合,那么可以将这两条路径合并,使答案更优
同时可以发现,树上点的权值只与起点的集合和终点的集合(可以发现这两个集合一定不相交)有关
因此我们可以树上DP,求出每条边的净流量,从而得出每个点的净流量,这个也就是这个点作为路径起点或终点的次数
知道了起点集合与终点集合,我们可以贪心得到字典序最小的答案
2019年9月27日星期五
扑克游戏
题目描述
有\(n\)张牌与两个人\(A,B\),第\(i\)张牌的点数为\(a_i\),保证\(n\)为偶数
现在将这\(n\)张牌打乱,再随机分为两堆数量为\(\frac n 2\)的牌,然后两人随机挑选其中一堆,这里的随机均为均匀随机
若将这两堆牌按顺序依次翻开,若\(A\)的那一堆的点数比\(B\)的那一堆的对应牌的点数大,则\(A\)加一分,否则\(B\)加一分,求两人最后得分的期望
要求输出答案与\(n!\)在模\((10^9+7)\)下的乘积
限制范围
\(Time:2000ms\quad Space: 256MB\)
\(n\le 10^5,n为偶数,1\le a_i\le 10^9\)
正解算法
由于两个人的分数一定为总和为\(\frac n 2\),因此只要计算出\(A\)的分数的期望,即可求出\(B\)的分数的期望
对每张牌分别考虑它对\(A\)的分数的贡献
设\(f(i)=|\j\mid a_i>a_j\|\),那么如果第\(i\)张牌被\(A\)选中,则有\(\fracf(i)n-1\)的概率对\(A\)的分数产生贡献,而每张牌有\(\frac 1 2\)的概率被\(A\)选中,因此第\(i\)张牌对\(A\)的分数的贡献为\(\frac f(i)2(n-1)\),\(A\)的分数的期望即为\(\left(\frac 12(n-1)\sum f(i)\right)\),将\(a_i\)排序后动态维护\(f(i)\)即可
带权平均数之和
题目描述
给定一个长度为\(n\)的正整数序列\(A\),以及一个长度也为\(n\)的权值数组\(W\)
定义\(f(l,r)=W_r-l+1\sum_i=l^rA_i\),求\(\sum_l=1^n\sum_r=l^nf(l,r)\quad mod\ (10^9+7)\)
限制范围
\(Time:2000ms\quad Space: 256MB\)
\(1\le n \le 3\times 10^5,1\le A_i,W_i\le 10^9\)
正解算法
设\(f(x)=\sum_i=1^xA_i,g(x)=\sum_i=1^xW_i\),那么有:
\[
\beginalign
\sum_l=1^n\sum_r=l^nf(l,r)&=\sum_u=0^n\sum_v=1^n-uW_v(f(u+v)-f(u))\&=\sum_i=0^nf(i)(g(i)-g(n-i))
\endalign
\]
求出\(f,g\)的值后,枚举\(i\),即可得到答案
排序
题目描述
给定一个\(n\times m\)的矩阵,其中一些格子为障碍,其他格子为空,现在需要在某些空格子中放铜币,满足:
- 每行每列都至少有一个铜币
- 若将所有同行或同列的铜币用边连接,那么所有铜币可以相互到达
现在问至少要多少枚铜币才能满足要求,且当铜币数最小时,摆放铜币的方案数
要求将方案数对\(998244353\)取模
限制范围
\(Time:4000ms\quad Space: 512MB\)
\(n\le 10^4,m\le 50\)
正解算法
将每一行与每一列看成一个点,每个空格子看做连接对应行和列的边,那么原问题即为求这个图的生成树个数
直接用矩阵树定理+高斯消元肯定是不行的,我们要考虑如何优化
可以发现,我们构造出的\((n+m)\)阶方阵的组成如下:
可以发现,这个方阵的绝大多数元素都是\(0\),且非\(0\)元素很多都分布于正对角线上,因此可以只处理两个\(n\times m\)的子矩阵与一个\(m\times m\)的子矩阵即可
2019年9月28日星期六
表达式求值
题目描述
有一个合法的、仅有0-9,+,*
的中缀表达式,由\(n\)个部分组成,第\(i\)个部分为\((s_i,r_i)\),代表将字符串\(s_i\)重复\(r_i\)遍
现在要求求出这个表达式在模\(998244353\)下的结果
限制范围
\(Time:1000ms\quad Space:512MB\)
\(n\le 10^4,r_i\le 10^9,|s_i|\le 10\)
正解算法
尝试用更快速的方式维护一个部分对答案的贡献
设有向量\(\left( \beginmatrix sum& stack& last& 1\\ \endmatrix \right)\),分别代表“上一个加号之前的集合”“上一个加号之后的到最后一个乘号为止乘积(若在上一个加号之后没有乘号就是1)”“上一个加号到现在所在符号的的结果”
那么可以发现,其转移方式为:
\[
\beginarrayc
add\quad +\qquad \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \rightarrow \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \left( \beginmatrix
1& 0& 0& 0\ 0& 0& 0& 0\ 1& 0& 0& 0\ 0& 1& 0& 1\\endmatrix \right)\ add\quad \times \qquad \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \rightarrow \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \left( \beginmatrix
1& 0& 0& 0\ 0& 0& 0& 0\ 0& 1& 0& 0\ 0& 0& 0& 1\\endmatrix \right)\ add\quad k\qquad \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \rightarrow \left( \beginmatrix
sum& stack& last& 1\\endmatrix \right) \left( \beginmatrix
1& 0& 0& 0\ 0& 1& k& 0\ 0& 0& 10& 0\ 0& 0& 0& 1\\endmatrix \right)\\endarray
\]
对每个部分都做一次矩阵快速幂,最后\((sum+last)\)即为答案(也可以直接)
无向图
题目描述
给定一个有\(n\)个点\(m\)条边的无向图(可能有重边自环),边有边权\(w_(u,v)\),点有点权\(x_i\),但有些点的点权未知
问在满足所给条件时,\(\sum_(u,v)\in E(x_u-x_v)^2\)的最小值
限制范围
\(Time:2000ms\quad Space:256MB\)
\(n\le 500,m\le 3\times 10^4,0\le x_i,w_(u,v)\le 10^5,w_(u,v)在值域上随机出现\)
正解算法
可以发现,对一个点\(i\)来说,当\(x_i=\frac\sum_(i,j)\in Ew_(i,j)x_j\sum_(i,j)\in Ew_(i,j)\)时,\(\sum_(i,j)\in E(x_i-x_j)^2\)最小
因此我们可以将所有点值未知的点设一个方程,则可用高斯消元法得出答案
最小值
题目描述
对于一个\(1\sim n\)的排列\(P\),设这个排列的权值为下列函数的输出:
int pos(int *P,int n)
int cnt=0,minx=n+1;
for(int i=1;i<=n;++i)
if(P[i]<minx) minx=P[i],++cnt;
return cnt*cnt;
现在有\(q\)次询问,每次问\(1\sim n\)的所有排列的权值总和,要求对\(998244353\)取模
限制范围
\(Time:2000ms\quad Space:256MB\)
\(1\le n,q\le 10^5\)
正解算法
方法一
可以发现\(pos(P)=|\i\mid \min_j=1^iP_j=P_i\|\)
由于\(i\)满足\(\min_j=1^iP_j=P_i\)的概率为\(\frac 1 i\),因此\(E(pos)=\left(\sum_i=1^n\frac 1 i\right)^2-\left(\sum_i=1^n\frac 1 i^2\right)+\left(\sum_i=1^n\frac 1 i\right)^2\)
方法二
可以发现,\(pos(P)=i\)的概率为\(S_1(n,i)\),因此可得\(\varDelta^2 ans_n=2(n!)\)
2019年9月29日星期日
序列
题目描述
给定正整数\(n,a,b\),问是否存在一个\(1\sim n\)的排列,使得这个排列的最长上升子序列长度为\(a\),最长下降子序列长度为\(b\),如果不存在,则输出No
,否则输出Yes
,并输出一组可行解
限制范围
\(Time:1000ms\quad Space: 512MB\)
多组数据,\(T\le 10,\sum n\le 2\times 10^5\)
\(n\le 10^5\)
正解算法
首先可以发现,有解的充要条件为\(a+b-1\le n\le ab\)
若一组数据有解,那么有这样一种构造方式:
将\(1\sim n\)的升序排列分为\(b\)段,使得最长的一段长度为\(a\),然后将这每一段当成一个整体逆序摆放,这样得出的解即为可行解
购物
题目描述
给定\(n\)个正整数\(s_i\),问有多少个正整数\(k\),满足以下条件:
\[
\exists S\subseteq\1,2,\cdots,n\\quad k\le \sum_i\in Ss_i\le 2k
\]
限制范围
\(Time:1000ms\quad Space: 512MB\)
\(n\le 10^5,s_i\le 10^9\)
正解算法
方法一
不考虑\(k\in\mathbb N\)的条件,用std::set
维护满足条件的\(2k\)的区间,每次加入一个数\(s_i\)等价于对每个区间\([l,r]\)均变为\([l,r]\cup[l+s_i,r+2s_i]\),由于有\(r\ge 2l\),因此不相交的区间数最多只有\(O\left(\log\left(\sum s_i\right)\right)\)的量级,因此暴力维护对时间复杂度影响不大
需要卡卡常
方法二
首先将所有\(s_i\)排升序,可以发现,对每个\(s_i\),它对答案的贡献为\(\left[\left\lceil\frac s_i 2\right\rceil,\sum_j=1^is_i\right]\),因此将每个\(s_i\)的贡献求出来,在去并集即可
计数
题目描述
有一棵含\(n\)个节点的二叉树,树上的点被编号为\(1\sim n\),且满足编号为\(i\)的节点在二叉树的前序遍历中恰好是第\(i\)个出现
若在中序遍历中\(i\)号点第\(A_i\)个出现,且满足给定的\(m\)个限制条件,均形如\(A_u_i<A_v_i\),即在中序遍历中\(u_i\)在\(v_i\)前出现
问有多少种不同的二叉树满足上面的条件
限制范围
\(Time:1000ms\quad Space: 512MB\)
多组数据,\(1\le T\le 5\)
\(n\le 400,m\le 1000\)
正解算法
设\(dp(root,size)\)为子树的根为\(root\),子树大小为\(size\)(即子树内的元素编号为\([root,root+size)\)),那么有:
\[
dp(root,i)=\sum_i=0^siz-1(dp(root+1,i)\times dp(root+i+1,siz-i-1)\times[\nexists t,子树一定不满足第t个限制条件])
\]
二维前缀和维护限制条件,暴力转移即可
2019年9月30日星期一
数据结构
题目描述
有一个正整数可重集合\(S\),一开始这个集合为空,现在要支持\(m\)个操作,每个操作有两种可能:
- 插入操作:在\(S\)中加入一个新元素\(x\)
- 修改操作,令\(S\)中所有元素均加一
每次操作结束后,需要输出\(\left(\sum_i\in Si^k\right)\)在模\((10^9+7)\)意义下的值,其中\(k\)为给定的正整数常数
限制范围
\(Time:1000ms\quad Space:256MB\)
\(m\le 2\times 10^5,k\le 50\)
正解算法
若正在处理第\(i\)次操作,且已经处理的修改操作有\(j\)条,答案为关于\(j\)的一个多项式\(f(j)\)
修改操作比较明显(直接修改\(j\)),考虑如何做插入操作
可以发现,若插入的数字为\(t\),那么这个数对后面的答案的贡献一定为\((t+j'-j)^k\),直接展开这个表达式,再加入到\(f(j)\)中即可
博弈
题目描述
有两个(绝对聪明的)人\(A\)和\(B\)在玩一个游戏
游戏在一个长度为\(n\)的整数序列\(\a_i\\)上进行,\(A\)和\(B\)轮流操作,\(A\)为先手
每次操作都选择序列首项与末项中的一个删除,直到只剩下一个元素为止
但是在开始游戏之前,\(A\)可以做刚好\(k\)次操作,得到一个对自己更有利的局面,当游戏开始时,\(A\)依旧会是先手
若\(A\)的目标为让最后剩下的元素尽量大,\(B\)的目标则相反,问最后剩下的元素会是多少
特别的,若输入的\(k=-1\),则需要求出\(k=0\sim n-1\)的所有答案
限制范围
\(Time:1000ms\quad Space:256MB\)
\(2\le n\le 2\times 10^5,-1\le k<n,0\le a_i\le 10^9\)
正解算法
可以发现,对一个长度为\(n\)的序列,在\(k=0\)时的答案一定有下面的关系
- \(n=2m\)时,\(ans=\max(a_m,a_m+1)\)
- \(n=2m-1\)时,\(ans=\max(\min(a_m-1,a_m),\min (a_m,a_m+1))\)
那么记录\(\max(a_i,a_i+1)\)与\(\min(a_i,a_i+1)\),即可快速算出结果
植物大战僵尸
题目描述
考虑以下这个植物大战僵尸游戏的变体:
现在有\(N\)个僵尸想来吃掉主角的脑子,其中第\(i\)个僵尸与房屋的距离为 ,它的坐标为\((0,a_i)\)
这个游戏是回合制的,地图中有两个赛道(即地图可以认为是\(2\times \infty\)的棋盘,同一个位置可能有多个僵尸)
每一回合中,以下三件事情按顺序发生:
- 游戏AI先行动,它可以选择把一些还活着的僵尸上下移动(即从\((0,a_i)\)移动到\((1,a_i)\)或者反之)
- 玩家行动,玩家会得到一个火爆辣椒,他可以把火爆辣椒放在第\(0\)行或者第\(1\)行,消灭这一行的所有僵尸
- 所有活着的僵尸向前走一步,也即从\((x,y)\)移动到 \((x,y-1)\)
任意时候,当某个僵尸与房屋的距离为\(0\)(即坐标为\((0,0)\)或\((1,0)\)),那么主角的脑子就会被吃掉,玩家输掉游戏,否则如果到所有僵尸都被消灭的时候,上述事件仍未发生,则玩家胜利
问AI在第一回合有多少种不同的行动策略使得玩家必败
答案需要对\((10^9+7)\)取模
限制范围
\(Time:1000ms\quad Space:256MB\)
多组数据,\(T\le 20\)
\(N\le 2000,1\le a_i\le 10^9\)
正解算法
可以发现,若给一个在\((x,y)\)的僵尸赋权值\(\frac 1 2^y\),那么有解的条件等价于存在一种划分为两部分的方法,使得每一部分的权值和均大于\(\frac 1 2\)
考虑搜索,设\(dfs(p,x,y)\)为枚举到\(a_i=p\)的所有僵尸时,两个部分中权值和与\(\frac 1 2\)的差为\(\frac x 2^p\)与\(\frac y 2^p\)时的答案,直接枚举这些僵尸的划分方法,暴力转移即可
剪枝:设剩下的僵尸总数为\(k\),若\(x+y>k\),则直接返回\(0\);若\(x\le 0\and y\le 0\),就返回\(2^k\)
Work to do
2019/8/6 以前(不包含本日)
2019/8/7 回文串——题解
2019/8/10 Monkey and Tree——题解
2019/8/11 抽卡大赛——题解(需要补充)
2019/8/11 最大区间子段和——题解
2019/8/12 yesorno——题解
2019/8/27 异或统计——题解
2019/8/27 集合统计——题解
2019/8/27 异或统计2——题解
2019/8/29 Reason For Living——题解
2019/9/8 speike——题解
2019/9/20 缩树游戏——题解
2019/9/21 不难题——题解
2019/9/23 树——题解
2019/9/23 路径——题解
以上是关于内部考试总结的主要内容,如果未能解决你的问题,请参考以下文章