2023NOIP A层联测9 (ACCODER 410)

2023NOIP A层联测9 (ACCODER 410)

2023年10月12日 / 比赛 / 信息学

代码与题面

A. 长春花

长春花有愉快的回忆的寓意。

题面及代码见文首下载包。

首先, O ( p 2 ) O(p^2) O(p2)的暴力不难想到,直接枚举 a a a b b b即可。

接着,你尝试 p = 99991 p=99991 p=99991 1 0 5 10^5 105以内最大的质数),你发现答案是 20 20 20,并不大。虽然这并没有单调性,但是你可以大胆猜测所有 p p p的答案都不会很大。如果你比较严谨,你可以打一下表,只需要几分钟时间,你会发现最大的答案为 31 31 31。那么我们枚举 a a a的时候只需要枚举到 31 31 31即可,时间复杂度近似于 O ( p ) O(p) O(p)

B. 紫罗兰

紫罗兰的花语寓意为永久的爱。

注意到是无向无权图,每次断开一条边,然后从一个端点到另一个做BFS,找到最短路径并统计方案数。判断是否为最小环,如果是统计答案。

实现上,对于松弛操作,如果成功松弛,那么重新赋值方案数;如果花费相同,那么加上方案数即可。

更多的,我们每个环可能被扫描多次,所以最后要去重。当然如果我们在输入的过程中,在加入每一条边前都做一次BFS,那么我们就不会重复统计。(我就是这个做法)

C. 天竺葵

天竺葵花语是幸福在身边。

先看 O ( n 2 ) O(n^2) O(n2)暴力,设 f [ i ] [ j ] f[i][j] f[i][j]表示考虑到第 i i i位选出了 j j j位,结尾数的最小值。

转移为: f [ i ] [ j ] = m i n ( f [ i − 1 ] [ j ] , a [ i ]   ( f [ i − 1 ] [ j − 1 ] ∗ b [ j − 1 ] < a [ i ] )   ) f[i][j]=min(f[i-1][j],a[i]\ (f[i-1][j-1]*b[j-1]f[i][j]=min(f[i1][j],a[i] (f[i1][j1]b[j1]<a[i]) )

想必大家都做过导弹拦截(洛谷),很容易发现 f [ i ] f[i] f[i]单调递增。

利用这个性质,我们在转移 f [ i ] f[i] f[i]的过程中,我们通过二分查找找到最大的 k k k使得 f [ i − 1 ] [ k ] < a [ i ] f[i-1][k]f[i1][k]<a[i],看看这个 k k k的性质。

  • 对于 j ≤ k j \leq k jk f [ i − 1 ] [ j ] < a [ i ] f[i-1][j]f[i1][j]<a[i]那么 f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]=f[i-1][j] f[i][j]=f[i1][j](不妨结合上文)。
  • 对于 j > k + 1 j > k+1 j>k+1 f [ i − 1 ] [ j − 1 ] ∗ b [ j − 1 ] > a [ i ] f[i-1][j-1]*b[j-1]>a[i] f[i1][j1]b[j1]>a[i](因为 b [ j − 1 ] ≥ 1 b[j-1] \geq 1 b[j1]1),那么 f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]=f[i-1][j] f[i][j]=f[i1][j]

如果我们去掉第一维,那么只有, j = k + 1 j=k+1 j=k+1时需要转移。时间复杂度降低至 O ( n log ⁡ n ) O(n\log n) O(nlogn)

D. 风信子

白色风信子代表纯真的爱情。

对于询问,我们注意到 ∑ k \sum k k不大,我们考虑将所有的可能以某种形式保存,放入优先队列中,我们最多只需要取 ∑ k \sum k k次,时间复杂度为 O ( ∑ k log ⁡ ∑ k ) O(\sum k \log \sum k) O(klogk)

关键是如何保存,如何取值?对于一个最初的询问 [ L , R ] [L,R] [L,R],其限制 L ≤ l ≤ r ≤ R L \leq l \leq r \leq R LlrR这等价于 L ≤ l ≤ R , L ≤ r ≤ R , l ≤ r L \leq l \leq R,L \leq r \leq R,l \leq r LlR,LrR,lr,我们考虑用线段树维护最大的 a [ l ] − a [ r ] a[l]-a[r] a[l]a[r],这要求我们取区间最大值,最小值,答案(以及位置),懒标记(有区间修改的操作)等。

Node operator +(const Node x,const Node y)
{
	Node z;
	z.l=x.l;
	z.r=y.r;
	z.z=0;
	if(x.x>y.x) z.x=x.x,z.a=x.a;
	else z.x=y.x,z.a=y.a;
	if(x.y<y.y) z.y=x.y,z.b=x.b;
	else z.y=y.y,z.b=y.b;
	z.v=x.x-y.y;
	z.p=x.a;
	z.q=y.b;
	if(x.v>z.v) z.v=x.v,z.p=x.p,z.q=x.q;
	if(y.v>z.v) z.v=y.v,z.p=y.p,z.q=y.q;
	return z;
}

这是合并操作(重载为加法,结构体为线段树结构体)。变量含义如下:

变量 含义
l 左端点
r 右端点
x 最大值
y 最小值
a 最大值下标
b 最小值下标
v 答案(即 a [ l ] − a [ r ] a[l]-a[r] a[l]a[r]的最大值)
p 答案中最大值下标
q 答案中最小值下标

其余的就是常规的区修区查线段树了(详细请见文首链接代码中的结构体Sgt),时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)

解决线段树后,我们开始考虑查询区间问题。为了方便表示,我们将要求为 L 0 ≤ l ≤ R 0 , L 1 ≤ r ≤ R 1 , l ≤ r L_0 \leq l \leq R_0,L_1 \leq r \leq R_1,l \leq r L0lR0,L1rR1,lr的区间表示为 ( L 0 , R 0 , L 1 , R 1 ) (L_0,R_0,L_1,R_1) (L0,R0,L1,R1)

因为取过的 l l l, r r r不能再取,所以我们需要分裂区间。但是我们需要分裂成什么样的区间,这就取决于什么样的区间好查询了。

如果区间为 ( L 0 , R 0 , L 1 , R 1 ) (L_0,R_0,L_1,R_1) (L0,R0,L1,R1),那么以下两种区间是好查询的。

  • 第一类区间 L 0 = L 1 , R 0 = R 1 L_0 = L_1,R_0 = R_1 L0=L1,R0=R1,上文的线段树的 v v v就是这个值(其实就和初始询问一致)
  • 第二类区间 R 0 < L 1 R_0 < L_1 R0<L1即相离,我们只要取上文线段树中的最大值减去最小值即可。

代码中的Add函数就是查询值的操作。

对于分裂操作,我们设最优解为 p p p q q q(最小值与最大值下标)。

对于第一类区间我们将其分裂成(因为 L 0 = L 1 L_0=L_1 L0=L1统一简写成 L L L R R R同理。):

  • ( L , p − 1 , L , L , p − 1 )   ( p > L ) (L,p-1,L,L,p-1) \ (p>L) (L,p1,L,L,p1) (p>L)
  • ( L , p − 1 , p , R )   ( p > L ) (L,p-1,p,R) \ (p>L) (L,p1,p,R) (p>L)
  • ( p , p , p , p )   ( p ≠ q ) (p,p,p,p) \ (p \neq q) (p,p,p,p) (p=q)
  • ( p , p , p + 1 , q − 1 )   ( p < q − 1 ) (p,p,p+1,q-1) \ (p(p,p,p+1,q1) (p<q1)
  • ( p , p , q + 1 , R )   ( q < R ) (p,p,q+1,R) \ (q(p,p,q+1,R) (q<R)
  • ( p + 1 , R , p + 1 , R )   ( p < R ) (p+1,R,p+1,R) \ (p(p+1,R,p+1,R) (p<R)

对于第二类区间我们将其分裂成:

  • ( L 0 , p − 1 , L 1 , R 1 )   ( p > L 0 ) (L_0,p-1,L_1,R_1) \ (p>L_0) (L0,p1,L1,R1) (p>L0)
  • ( p , p , L 1 , q − 1 )   ( L 1 < q ) (p,p,L_1,q-1) \ (L_1(p,p,L1,q1) (L1<q)
  • ( p , p , q + 1 , R 1 )   ( q < R 1 ) (p,p,q+1,R_1) \ (q(p,p,q+1,R1) (q<R1)
  • ( p + 1 , R 0 , L 1 , R 1 )   ( p < R 0 ) (p+1,R_0,L_1,R_1) \ (p(p+1,R0,L1,R1) (p<R0)

(为了防止笔误带来的影响,可以结合代码)

最后记得重载区间比较函数。

你可能感兴趣的:(比赛,信息学,算法,c++)