Training-“四光年之外去流浪”
代码放太多,卡炸了,遂全删
CF780G Andryusha and Nervous Barriers
紫。
比较简单,先按照高度排序并重编号,扫描线找边缘下落的球分裂的第一块板子,这部分可以线段树二分,找编号最大的要求高度超过它的板子。
可以发现依赖关系一定是编号大依赖编号小,可以递推。
CF1578B Building Forest Trails
紫。
首先把圆拍到序列上,要求每条边 \(x<y\),如果两条边 \((x_1,y_1),(x_2,y_2)\) 满足 \(x_1\le x_2\le y_1 \le y_2\) ,那么就会交叉。
考虑对每个连通块的连边方式做一个改变,变为按顺序从小到大连,而且观察到每个连通块构成的区间要么包含,要么不交。
这里应该会有一个 \(\log^2\) 的做法,就是记录一下 pre 和 next,然后线段树二分。
实际上还能更优,考虑记录每个 \(x\) 上方的线的数量 \(h_x\),不包括连到 \(x\) 的线。
可以发现相邻两个点之间的 \(h_x\) 的变化量不超过 1,因为要么在上一个点开了一条新线,要么在这里收回一条线。
接下来考虑哪些线会和 \((x,y)\) 交叉,一种开头在 \(x\) 前面,结尾在中间,那么必然有一条线经过 \(x\),因为区间相互包含或不交,那么在中间的收束点的 \(h\) 一定是比 \(h_x\) 小的。
所以每次可以选 \(h_x,h_y\) 中较大的去找,然后合并区间。
合并分为两种情况,一是不交,那么前面右端连后面左端,一种是包含,那么就是去掉覆盖小区间的那一段,再加上小区间到大区间的两条边,其实就是小区间上的覆盖条数 -1。
CF1083C Max Mex
紫。
先考虑怎么处理一组询问,就是依次加入每个点,然后判断是否在一条链上。
然后考虑上树,这里可以维护一个更强的限制,就是每个区间 \([l,r]\) 内的是否都在一条链上。
合并上就是判断两个链是否能拼在一起,一种方法就是维护端点,然后一侧往另一侧插入,最后线段树二分。
P11833 [省选联考 2025] 推箱子
蓝。
弱智但比较难写。
按时间排序,每次优先满足时间限制较紧的。考虑满足的过程中,以向左移动为例。
在移动的过程中考虑会碰到哪些箱子,记当前下标为 \(i\),那么现在移动的结果就是 \(b_i-k,b_i-k+1,\dots,b_i\),所以在它前面的点 \(j\),如果位置在 \(b_i-i+j\) 的后面,就要移动。
然后考虑如何快速找,这里给一个较为方便的解法,首先把箱子向右移动 \(i-j\),这样每个点的目标位置就是 \(b_i\),就可以线段树二分。
最后就是区间加等差数列和区间赋值等差数列,外加区间求和计算贡献,向右移动同理。
P11831 [省选联考 2025] 追忆
黑。
因为是自己做的,所以比较神秘。
首先 bitset 搞出连通性,然后考虑对操作分块,但是还有 \(l,r\) 的限制,所以继续对值域分块。
这个时候可以对每个值域块跑 \(O(n)\) 的递推找最大值,散块暴力判断。被操作的部分因为值不确定,所以单独拿出来求出值后求贡献。
这里注意一下常数,对每个操作块所有整块一起跑,然后在询问处取需要的,这样常数比较小。
块长因为 \(n,q\) 同阶,所以可以取到 \(n^{\frac{2}{3}}\),时间复杂度 \(O(\frac{n^2}{w}+n^{\frac{5}{3}})\)
CF1809G Prediction
紫。
counting!
考虑形式化一下这个题意,就是 \(\forall i |\max_{j=1}^{i-1} p_j-p_i|>k\),这东西从小到大放显然不能做。
考虑从大到小,在放 \(x\) 的时候会有哪些情况,一个是插在一个数的后面这里是如果开头的数 \(y\) 满足 \(y-x>k\) 那么每个数的后面都可以,否则要少一个可行位置。
另一种就是直接放在前面,同样要求差。
可以发现一个关键在于这个 \(max\) 序列,记 \(f_i\) 表示 \(max\) 序列的开头是 \(a_i\),那么首先差比 \(k\) 小的数的方案数就已经确定了,其余的容易前缀和处理。
CF1861F Four Suits
黑。
有一个东西必须枚举,就是在哪个花色取到最值,然后可以证明如果这个花色不顶满一定不优。
然后考虑网络流,先二分一个其余部分的上界,源点向花色连剩余数量的边,其余人向汇点连还要收获的牌 \(d_i\),中间就是可以拿的最多的牌的数量,最大流恰好是所需牌数才能成立。
根据最大流-最小割定理,转成求这个图的最小割,首先必须枚举左边和源点断开的点集 \(S\) 的补集,右边每个点的贡献就是 \(\min(popcount(S)*mid-\sum_{j\in S}a_j,d_i)\)。
然后可以发现这个东西可以轻松解出来一个变化点,就是一个等差数列+一段 \(d_i\),做两次差分预处理就可以了。
预处理核心代码
for(int s=1;s<16;s++)
{
int cnt=0;
for(int i=0;i<4;i++) cnt+=((s>>i)&1);
for(int i=0;i<M;i++) p[i]=c[i]=0;
for(int i=1;i<=n;i++)
{
int sum=0;
for(int j=0;j<4;j++) sum+=((s>>j)&1)*a[i][j];
int x=(d[i]+sum)/cnt;
c[1]+=cnt,c[x+1]-=cnt;
p[0]-=sum,p[x+1]+=sum-cnt*x,p[x+1]+=d[i];
}
for(int i=1;i<M;i++) c[i]+=c[i-1];
for(int i=1;i<M;i++) p[i]=p[i-1]+p[i]+c[i];
for(int i=0;i<M;i++) s2[s][i]=p[i];
}
CF1919E Counting Prefixes
紫。
???咋这么若只呢?原来我的代码能力是若只啊!
比较好想,就是画出每个变化的折线图,保留一条线下的部分,就是一些连续段。
所以考虑 \(f_{i,j,0/1/2/3}\) 表示考虑到数字 \(i\) 有 \(j\) 个连续段,开头和结尾是否被占据。
然后就是枚举有多少个连续段被合并,随便组合数一下就完了,关键来了,如果最后所有点都用于合并,就不需要管放的情况,直接就是 1,优先级高于组合数。
我恨你!
int tmp=x-(j*2-l-val[k]);
ll v=C(j-1,l)*C(tmp+j-l-val[k],j-l-val[k])%mod;
if(!tmp) v=C(j-1,l);
f[d][j-l+tmp][k]=(f[d][j-l+tmp][k]+f[d^1][j][k]*v)%mod;
AT_utpc2025_k Keep or Gamble
\(\varnothing\)。
aaa,不会概率,做了一辈子。
\(P\) 肯定没什么影响,考虑现在已经选了 \(x\) 个 \(U\),\(y\) 个 \(T\),那么如果摸到 \(C\),贡献就是 \(-x-y\)。
然后就可以把贡献拆到每一步上,就是 \(\max(0,\frac{2*(u-x)+(t-y)-c*(2*x+y)}{u+t+c-x-y}\)。
然后考虑每一步的概率,就是视作一起放开,恰好有 \(x\) 张 \(U\),\(y\) 张 \(T\) 的概率,就是 \(\frac{C_u^xC_t^y}{C_{u+t+c}^{x+y}}\)。
记和为 \(s=x+y\),那么枚举 \(s\) 可以求出 \(x\) 的范围,然后整理式子得到 \(\frac{1}{C_{u+t+c}^{s}}(\sum C_u^xC_t^{s-x})(2*u+t-(c+1)*(x+t))\)
然后根据 \(C_n^m m=C_{n-1}^{m-1}n\) 所以可以转变成对于一个式子 \(\sum C_u^xC_t^{s-x}\),求前面的若干项和。
项数变化直接加就可以了,上指标和变化考虑组合意义,就是在 \(u+t\) 个中选 \(s\) 个且 \(u\) 中不能选超过 \(k\) 个。
所以加入之后就是先选一个新的,再减去超出的。
核心代码(完整的就是做两遍类似的)
for(int i=0;i<=u+t;i++)
{
if(u*2+t-(c+1)*i<=0) break;
int l=(u*2+t-(c+1)*i)/(c+1);
if(x<i)
{
val=(val*(u+t-x)-C(u,y+1)*C(t,x-y)%mod*(y+1))%mod*inv1[x+1]%mod;
x++;
}
while(y<l)
{
y++;
val=(val+C(u,y)*C(t,x-y))%mod;
}
while(y>l)
{
val=(val-C(u,y)*C(t,x-y))%mod;
y--;
}
ll v=qpow(C(c+u+t,i),mod-2)*inv1[u+t+c-i]%mod*(2*u+t-(c+1)*i)%mod;
ans=(ans+val*v)%mod;
}
CF2174F Mosaic Tree
黑。
度数相关,考虑 prufer 序列,就是对每个颜色,选出若干个位置,然后规定出现次数的奇偶性,这里就有一个 \(O(n^3)\) 的 dp 了。
接下来考虑优化这个做法,背包所以想到多项式,三模 NTT 大概做不了。可以发现如果颜色 \(k\) 有 \(cnt_k\) 个点,\(x\) 条边,那么贡献的方案数就是 \(cnt_k^x\)。
考虑构造指数生成函数 \(f(x)=\sum cnt_k^i\frac{x^i}{i!}\),系数的公式就是 \(e^{cnt_k}\),答案就是第 \(n-2\) 项的系数 \(*(n-2)!\)。
奇数就是 \(\frac{e^{cnt_k}-e^{cnt_k}}{2}\),偶数是 \(\frac{e^{cnt_k}+e^{cnt_k}}{2}\)
然后乘起来就是 \(\frac{1}{2^m}\prod (e^{cnt_i}+s_i e^{cnt_i})\)。
所以这部分就可以直接 dp 了。
CF2161F SubMST
紫。
构造就是____。*3000 反正不是人做的。
从下往上考虑,对于当前节点 \(x\),如果它不是深度最浅的节点,那么必然存在一条边连向深度小于等于它的点。
所以可以对每个点取最小的距离就可以了,如果距离相同,可以事先按照 bfs 序编号,然后对每对点看有多少情况存在边。
AT_jsc2025_final_c Prefix Bounding Box, Mod, Minimize
蓝。
最大值最小,3000 的范围也像是能带 \(\log\) 的,所以考虑直接二分,小于当前值 \(mid\) 的部分才会有贡献。
考虑到面积就是横坐标极差和纵坐标极差的积,这个东西是可以直接维护的。
接下来考虑转移,设 \(f_{i,j}\) 表示有 \(i\) 个数已经放好,横坐标极差 +1 是 \(j\),这里 +1 是为了转成位置数量,在只有一个点的时候方便表示。
接下来考虑转移,假设当前在放第 \(i\) 个点,那么有两种情况:
一是放在已经有的一段区间 \(j\) 的中间,方案数就是空位个数 \((j-i+1)\)。
二是放在外面,这样区间就会扩大,对于特定的长度 \(j,k\) 满足 \(j<k\),从 \(f_{i-1,j}\) 到 \(f_{i,k}\) 有两种情况,分别是左端和右端。
后面这个部分可以前缀和优化,最后判断 \(f_{n,n}\) 有没有值,就是能否成立。
CF1844H Multiple of Three Cycles
黑。
*3400 反正每一步都在看题解。
首先其实每次就是把两段连到一起,之后的操作中可以视为一个节点,然后就是每个节点的权值就是长度对 3 取模的余数。
记余数为 \(1,2,0\) 的点的数量分别为 \(a,b,c\),因为最后要求是 3 的倍数,\(c\) 的放置就对答案没有影响了,任意插在一个位置就可以了 \(\frac{(a+b+c)!}{(a+b)!}\)。
然后设 \(f_{i,j}\) 表示有 \(i\) 个为 \(1\) 的,\(j\) 个为 \(2\) 的,两个 \(2\) 连起来就是 \(1\),两个 \(1\) 同理。
对边进行枚举,就是 \(aa,ab,bb\) 三种,对应到的状态分别是 \(f_{a-2,b+1},f_{a-1,b-1},f_{a+2,b-1}\),这里 \(ab\) 这个状态就是形成一个 \(c\) 段,所以会涉及一个插入或者直接闭合的问题,要再带上系数 \((a+b-1)\)。
所以有式子:
钦定编号最靠前的 \(a\) 必选:\(f_{a,b}=(a-1)f_{a-2,b+1}+b(a+b-1)f_{a-1,b-1}\)
钦定编号最靠前的 \(b\) 必选:\(f_{a,b}=(b-1)f_{a+1,b-2}+a(a+b-1)f_{a-1,b-1}\)
但是因为每个询问要求的起点都不一样,所以考虑逆过来,然后就是一个知二求二解方程。
CF1419F Rain of Fire
紫。
看错题了……显然可以二分。
因为加一个点最多只能连 4 个方向,所以连通块个数 >4 一定不行。
分讨!
=2 \(O(n^2)\) 枚举不在一个连通块的两个点,然后看能不能用一个点把它们连上。
=3 一个方向上要有两个连通块,这条线段一定是越短越好,所以找 \(x\) 或 \(y\) 相同的相邻点,然后枚举另一个方向上的点,求出交点后判断。
=4 两条线段求交。
CF2122G Tree Parking
紫。
想不到拓扑序,如何呢?
首先考虑对于一个固定的树,怎么求它的方案数。
可以发现对于一个点 \(u\),它儿子之间的顺序是互不影响的,所以直接求一个可重复组合然后继承就可以了。
然后考虑当前点,可以发现,如果这个点的 \(l,r\) 之间有儿子的端点,那么一定会挡住,所以必须相连,两部分合起来方案数就是 \(\dfrac{siz_u}{\prod{v\in son(u)} siz_v}\)。
然后乘起来就是整棵树的答案,整理一下,就是 \((2n-1)!\prod_{u=2}^n \dfrac{(2siz_u-1)!}{(2siz_u)!}=\dfrac{(2n)!}{2^n\prod_{u=1}^n siz_u}\)。
有根树的拓扑序个数:
从简单的情况开始考虑,就是只有一层,那么就是下面的任意去排列。然后考虑父亲和儿子数量的关系,因为父亲这里一定是它在最后,其他任意排列,所以直接继承儿子,然后可重复组合就可以了,最终就是 \(\dfrac{n!}{\prod siz_u}\)。
然后把这部分拆出来,相当于就是一串固定系数乘上拓扑序的个数。
然后把贡献拆到每个拓扑序上,考虑对于一个拓扑序,有多少种叶子为 \(k\),记为 \(f(n,k)\),有:
\(f(n,k)=(n-k)f(n-1,k-1)+(k)f(n,k)\)
就是倒着加入,这样每次新加入的点都是叶子,分成接在叶子/其他,可以发现这就是欧拉数 \(E(n-1,k-1)\)。
然后见:https://www.cnblogs.com/UKE-Automation/p/19605252
因为固定最后一位是 \(1\),所以拓扑序的数量就是 \((n-1)!\),答案:\(\dfrac{(2n)!}{n2^n}\sum_{i=0}^{k-1}(-1)^iC_n^i(k-i)^{n-1}\)
CF587E Duff as a Queen
紫。
涉及异或,直接线性基,麻烦的点在于怎么区间修改。
考虑差分数组,因为每次选一个差分数组中的数,就相当于直接将两个数各选一次,所以可以单点修改了。
CF878D Magic Breeding
紫。
bitset 神力!
首先考虑到这个东西最后是一个类似于 DAG 的结构,可以从前面推到后面。但是因为初始的状态实在太多,所以导致复杂度过高。
因为 \(k\) 很小,一个思路就是枚举排列,但是 \(12!\) 依然很大。考虑到一个二分的思想,比 \(x\) 大或等于的视为 1,其余视为 0,如果最后是 1,那么就有 \(ans\ge x\),反之亦然。
所以这样每一位就只有 0 和 1 两种情况了,而且取 max 和 min 就是与和或,所以直接上 bitset 就是对的。
CF840E In a Trap
黑。
其实是一个比较经典的 trick,就是先拆位,拆成前后两部分,这里比如就是各 8 位。
对每个点,向上找 256 个点,如果在这个点到 \(v\) 的距离是 \(256k\) 的时候,那么后面 8 位所异或上的值就是到当前点的距离。
然后建字典树,预处理前 8 位取每个值的时候的最大结果。
询问的时候,先跳整块,每次增加前面的值,然后当点不够 1 块的时候暴力就可以了。
CF1458F Range Diameter Sum
黑。
*3500 不像是人能会的。
首先相当于这些点组成的虚树的直径,由直径的性质,这个东西是可合并的,所以可以 ST 表维护。
然后考虑如果我们加入一个点 \(i\),那么树的直径会怎么变,显然 \(f(i,j)\ge f(i+1,j)\),而且这个变化量是很有限的。
如果 \(f(i,j)>f(i+1,j)\) 那么就必然有 \(i\) 为新的直径端点,而且可以感性理解一下,\(j\) 越大,虚树上的点越多而且包含前面的所有,加入 \(i\) 后增加的距离一定不增。
而且这个增量相同的段数一定不超过 \(n\sqrt n\) 所以可以扫描线处理。
P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I
紫。
波动过的。
考虑分块,记录每个数在块内的前后缀逆序对个数,以及每个块内小于等于 \(x\) 的数的个数,对这个做一下前缀和,然后就可以根据这个求出块 \(i\) 到块 \(j\) 的逆序对数。
然后对于一个询问,如果在一个块内,考虑先对前缀个数做差,然后去掉区间外和区间内的贡献,具体可以对每个块提前排好序,直接扫一遍就行了。
然后是不在一个区间,整块直接用,散块到整块就可以用之前的计数数组,然后就是散块之间,因为已经提前排序,所以可以直接归并。
P6774 [NOI2020] 时代的眼泪
黑。
分块,分块,分块!
其实是为了这道题写了上面的,相当于在上一个的基础上加了一个值域的限制。
每个块内的小于等于 \(x\) 的个数的前缀和 \(cnt\) 仍然要预处理,这样散块与整块,散块与散块的处理是类似的。
但是值域会让很多东西都很麻烦,考虑先对每个块排序,然后
如果 \(l,r\) 在一块内,因为值域的问题,没有办法预处理前后缀了,可以记录每个位置 \(x\) 所在块前面排名小于 \(y\) 的数的个数,这样做差求和就行了。
然后是整块,块内因为值域很小,所以可以直接枚举上下界。
块之间比较麻烦,一种方法是对于每个块 \(i\),向左枚举一个端点 \(j\),这里必须是某个整块的端点,再枚举一个排名 \(k\),然后求 \(j\) 到 \(i\) 之前的一个块中,比排名为 \(k\) 的数小的逆序对数。
然后就可以做差,交叉部分是比较好算的。
CF1508F Optimal Encoding
黑。
可以先把每个区间里的所有关系先全部连出来,然后考虑哪些能删,如果 \(u->v,v->w,u->w\) 都有边,那么 \(u,w\) 之间的边就没有必要存在。
考虑把贡献拆到边上,考虑它什么时候出现,什么时候消失。
如果中间有一个值 \(x\) 恰好满足 \(a_u<a_x<a_v\),那么 \((u,v)\) 这条边就不会存在。
出现就是在恰好有一个区间包含 \(u,v\) 的时候,消失就是找到前后最近的值在 \(a_u,a_v\) 之间的位置,一个区间包含 \(u,v\) 的同时包含其中一个就消失。
这都可以用主席树简单维护,关键在于有 \(n^2\) 条边,直接做就是假的,考虑减少边数。
考虑到区间相关,如果用类似莫队的方法去做,那么每次端点移动至多会有 1 个新边产生,这东西不好插入,所以用个回滚莫队就能减少边数,对每条会出现的边分别求就可以了。
CF1990F Polygonal Segments
黑。
这题真好吧。
首先转化条件,如果一些数可以构成多边形,那么最大数必然小于和的一半,这是充要条件。
大力上线段树,合并的时候如果不能构成,那么就从最大值处断开,然后可以发现一边必然被一个区间包含,跑另一边就可以了。
可以发现每次和必然减半,所以至多 \(log\) 次,所以最后大概是个 \(log^3\) 的复杂度,常数较大但跑不满,实际飞快,8s 肯定是能过的。
P6729 [WC2020] 有根树
黑。
好难……还卡常……其实是我偷懒写了 \(\log^2\) (:
首先一定是越靠近根 \(w\) 值越大,而且贪心策略就是把较大的放入 \(C\) 集合,所以不存在小数干扰大数的问题。
可以发现一定有一种最优方案使得 \(a\ge b\),因为如果 \(a<b\),一定可以将最大的换到 \(C\) 集合中,答案一定不劣,此时必然有 \(\min_{v\in c} w_v\ge\max_{v\notin c} w_v\)。
接下来考虑修改问题,可以发现改一个点之后只有到根的链上的 \(w\) 值发生了改变,而且只有一个值在 \(C\) 集合的存在性会被改变。
当修改完链上的 \(w\) 之后,可能会有一个点使得不满足 \(\min_{v\in c} w_v\ge\max_{v\notin c} w_v\),把它处在集合的位置调换。
然后就是按照上面的过程做,这里可以用线段树维护集合外最大值,集合内最小值,和它们对应的位置,然后树剖修改。
P8078 [WC2022] 秃子酋长
紫。
回滚莫队板子,维护链,然后每次从链上删点,5e5,5s,根号还是能过的。
P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II
紫。
最简单的莫队做法,就是直接树状数组查有几个大于/小于这个数,时间复杂度 \(O(n\sqrt n \log n)\)。
考虑这些查询,可以做一个差分以移动右指针为例,就是区间 \([1,l-1]\) 和区间 \([1,r-1]\) 之间大于 \(a_r\) 的数的个数,这样的共 \(O(n\sqrt n)\) 个。
可以离线下来扫描线,每次加入一个数,然后查询,这里平衡复杂度可以 \(\sqrt n\) 加 \(O(1)\) 查。
但是储存这些询问空间必炸,考虑到每次 \(l/r\) 的移动就是一个连续段,所以存一个段就可以了,而 \([1,r-1]\) 对 \(a_r\) 的贡献可以预处理前缀和。
P6778 [Ynoi2009] rpdq
黑。
写上面的是为了写这个。
考虑把贡献拆到每一条边上,那么每次加点就是对到根链的权值求和,再将这些边的系数 +1。
然后正常莫队应该是可以做到 \(O(n\sqrt n \log^2)\) 的,那为啥不暴力?
接下来考虑莫队二次离线,那么就要求 \(\sqrt n\) 修改 \(O(1)\) 查询。
最简单的方法是随机撒点或者每 \(siz\) 大概在 \(\sqrt n\) 分一次,但是因为分叉很多,在这个题都不好转移。
可以发现最下面是无关的,所以 \(siz\) 够了直接割下来,然后可以按照 \(\sqrt n\) 的大小把链拆开就行。
然后考虑怎么修改,块内就是暴力对每个边加权,如果是在最底下,那么因为上面连接的不一定是一个链的端点,所以还要对这条链重复操作。
然后剩下的都是整条链的贡献,直接打 tag 树上求和就行了,因为这样的链最多 \(\sqrt n\) 条,所以复杂度正确。
P13826 [Ynoi Easy Round 2026] 寒蝉鸣泣之时
紫。
啊艹,sb 四模后的第一道,能不能不要再考 AI 相关的作文了!!!
考虑扫描线,然后分块,就是一个区间加,求值个数的问题。
考虑到如果是整块变一个相同的值,那么相当于按照对 \(m\) 的余数分组,每个组只是位置偏移,但是和不变。
所以可以记录改变的量,然后找对应的组。
对于散块,因为修改数量很少,所以暴力重构就是对的。
还有就是统计答案的时候不能遍历每一个可能的值,要建一个链表处理有值的位置。
最后是卡常上,因为空间比较紧,所以考虑离线处理每一个块。
P7881 [Ynoi2006] rmpq
黑。
神人交互,强制在线。
相当于每次把平面分成两半,染成不同的颜色,最后平面一定是 \(O(n^2)\) 级别个等价类。
考虑操作分块,每块只做 \(O(\sqrt n)\) 次操作,那么每块就只有 \(O(n)\) 级别的矩形。
考虑怎么求这些矩形的值,可以分治然后双指针归并,时间复杂度 \(T(n)=n^2+2T(\frac{n}{2})=O(n^2)\)。
统计答案二分位置然后暴力处理散块就行了,注意卡的点在于分治,所以块长尽量小一点次数更少。
P13827 [Ynoi Easy Round 2026] 寒蝉鸣泣之时·业/P10540 [THUPC 2024 决赛] 古明地枣的袜子
黑。
这咋样例都不带变的?写上面的是为了为写这个。
首先前缀加是不好做的,转成点加后缀最大值,但是线段树常数大,\(O(n\sqrt n \log n)\) 肯定过不了。
对于一个询问,我们看是怎么做的,相当于按照 \(x\) 从大到小排序,\(x\) 相同按照 \(y\) 从小到大排序,此时就是 \(y\) 的最大前缀和。
放到操作序列上,先按照上述方法排序,对每一个点进行考虑,可以发现如果以区间端点 \(l,r\) 为坐标系,那么它有贡献的就是一个矩形。
而且因为求前缀和最大值,有结合律没有交换律,就是 rmpq。
注意,因为这里卡空间,所以对每个块求完之后要立刻统计答案,不算特别卡。
P13828 [Ynoi Easy Round 2026] 寒蝉鸣泣之时·卒
黑。
咋就又开始一天一道题了。
首先 \(10^5\) 的范围复杂度大概就是 \(n\sqrt n\) 状物,和一定那么可以根号分治。
最暴力的做法就是 \(O(n)\) 把树遍历一遍,然后开个桶计数,当选出的点比较多的时候,建立的虚树和原树基本一样,这个方法是比较优的。
接下来考虑选出点个数比较少的情况,这些点构成的树一定是可以拆成 \(2t\) 条从根到某个点的链差分后的结果。那对于一个链 \((1,x)\),我们就需要知道其余边和它之间的相同数对个数,最后乘上对应权值求和。
暴力枚举每个点,两两配对肯定不行,考虑怎么减少需要处理的量,考虑树分块,每次只求块的端点到根这一段与根到每个点之间链的贡献。这样我们就要求链上不能有分叉,并且分的块数不超过 \(\sqrt n\),任意两个块端点之间的距离不超过 \(\sqrt n\)。
这里可以参考 [Ynoi2009] rpdq 的分块方法,首先将大小小于 \(\sqrt n\) 的子树分成一块,此时剩下的部分分叉数必然小于等于 \(\sqrt n\) 否则一定可以再分出子树,这部分按照 \(\sqrt n\) 的长度一拆就可以了。
统计答案的时候,此时的散块就有两种情况,一种是在链块上,那么按照正常的树分块去跳,否则先跳到子树块的根,再往上到最近的链块就和前面一样了。
考虑统计答案,整条到根的链 \((1,x)\) 可以拆成整块 \(a\) + 散块 \(b\),那么对于两条链 \(x,y\),答案就是 \(a_x*y+a_y*x-a_x*a_y+b_x*b_y\),为了好写可以乘个 2 求有序数对,记得要减去相同的情况。
散点的数量比较少,暴力就可以了,其他的是好预处理的,这题不算特别卡常,实现不太烂的情况下应该不会被卡的很严重。
P4389 付公主的背包
紫。
考虑每个物品就相当于一个多项式,背包的结果就是所有多项式乘起来的对应项系数。
做 \(m\) 次 NTT,复杂度还不如暴力,考虑到 \(x^v+x^{2v}\dots=\frac{1}{1-x^v}\),可以求这个东西的积再转回去。
但是直接乘是 \(O(2^n)\) 的,也不行,考虑弄成指数,因为 \(\ln(1-x)=\sum \frac{x^i}{i}\),所以可以简单的求出系数求和。
最后 exp 求逆弄回原多项式就行了。
P3784 [SDOI2017] 遗忘的集合
黑。
就是上面那个题的逆运算,因为模数的问题,所以要用 MTT。
首先求倒数,然后求 \(\ln\),这样就得到了指数和的形式,对第 \(i\) 项乘以 \(i\),此时这个位置的值就是它的所有存在的因子的和。
所以每个点更新一下倍数,然后有值的位置就是答案。
CF2206B Subtree Removal Game
\(\varnothing\)。
啊啊啊我为什么不会啊,为什么会认为有无论谁先手后手都必胜啊。
考虑二分,大于的是黑点,其他是白点,先手就是尽量让最后留白点。
子树分成三类,一类是白色,最初的先手必胜,一类是黑色,最初的后手必胜,剩下的是空集,谁先手谁胜。
在一个子树内一定是要尽快解决对手的子树,去抢都有可能赢的部分,而且发现这些取光其实不影响先后手,所以只用判断有颜色的部分就行了。
CF2206D Christmas Tree Un-decoration
紫。
考虑暴力 dp 怎么做,设 \(f_i\) 表示 \(i\) 的最优解,那么有 \(f_{i}=\max(a_i,\sum_{v\in son(u)} f_v)\)。
带修就轻重链剖一下,每个点记录轻儿子的 dp 值和,跳重链修改即可。
P4002 [清华集训 2017] 生成树计数
黑。
这题巧是真的巧,科技也是真的多。
首先生成树考虑 prufer 序列,出现次数为 \(d_i\),那么度数就是 \(d_i+1\),答案式子就是:
提出 \((n-2)!\prod a_i\),那么每个 \(i\) 的贡献就剩下 \(a_i^{d_i}\frac{1}{d_i!}(d_i+1)^m\prod a_j^{d_j}\frac{1}{d_j!}(d_j+1)^m\)。
令 \(A(x)=\sum \frac{1}{k!}(k+1)^m x^k,B(x)=\sum \frac{1}{k!}(k+1)^{2m} x^k\)
答案就是 \(\sum \frac{B(a_ix)}{A(a_ix)} \prod A(a_j x)\)
可以发现,后面的东西可以先求一个 \(\ln\),然后前后两部分都是一个多项式求和的形式,那么现在需要对每个位置求 \(\sum a_i^j\)。
因为 \(\sum a^kx^k=\frac{1}{1-ax}\),所以要求的就是 \(\sum \frac{1}{1-a_ix}\) 的每一项系数。
展开,分母就是 \(\prod (1-a_ix)\),分治一下就行了,分子对比系数,每一个位置乘上 \((n-i)\)。
[ABC452G] 221 Substring
紫。
转化一下,假设一段连续的 \(a\) 的长度是 \(b\),那么如果 \(a=b\),那么加入一个数 \(a\),如果 \(a<b\),就加入一个数 0,否则加入 \(a,0,a\)。
那么所求就变成了不包含 0 的不同子串数,SA 搞一下就好了。

浙公网安备 33010602011771号