2019 Multi-University Training Contest 3

原来我不只是不会数学和数据结构,连图论和DP也8会 = =

1002 Blow up the city

题意

给出一张 n   ( n ≤ 1 0 5 ) n\ (n\le10^5) n (n105)个点的有向无环图(不一定连通),每个出度为 0 0 0的点可视为一个指挥部。
现在有 q   ( q ≤ 1 0 5 ) q\ (q\le10^5) q (q105)次询问,每次询问会指定两个点作为补给站。若摧毁一个点之后,任意一个补给站无法到达任何指挥部,那么这算做一个成功的方案,每次询问需要求出有多少种成功的方案。

题解

支配树,所有边取反,再设置一个超级源点向原图中每个指挥部连边,超级源点作为支配树起点。
对于两个补给站,求出LCA去重。
不会支配树,挂起来等补题。

1004 Distribution of books

题意

给出一个长为 n   ( n ≤ 1 0 5 ) n\ (n\le10^5) n (n105)的数列,每个数字 a i a_i ai满足 − 1 0 9 ≤ a i ≤ 1 0 9 -10^9\le a_i\le10^9 109ai109
可以舍弃末尾任意数量的数字,剩下的数列要能够分成 K ( K ≤ n ) K(K\le n) K(Kn)个非空的区间,每个区间内求和,再对这 K K K个和取最大值,求这个最大值最小能是多少。

题解

二分 + DP。
二分答案。每次二分的检测为:能否分出 K K K个区间,每个区间求和小于二分值。
这一步用DP解决, D P [ i ] DP[i] DP[i]表示前 i i i个数字最多能被分成多少个区间,且每个区间求和小于二分值。
设二分值为 L i m Lim Lim容易想到状态转移方程式: D P [ i ] = m a x { D P [ j ] + 1 } ( j &lt; i   &amp;   S u m ( j + 1 , i ) ≤ L i m ) DP[i] =max\{DP[j]+1\}(j&lt;i\ \&amp;\ Sum(j+1,i)\le Lim) DP[i]=max{DP[j]+1}(j<i & Sum(j+1,i)Lim)
因为 a i a_i ai有正有负,合法的 j j j不是连续的。
S [ i ] S[i] S[i]为前缀和,那么 j j j满足 S [ i ] − S [ j ] ≤ L i m S[i]-S[j]\le Lim S[i]S[j]Lim,移项可得 S [ j ] ≥ S [ i ] − L i m S[j]\ge S[i]-Lim S[j]S[i]Lim,对于所有前缀和离散化,做一个值域线段树或者反向做一个树状数组均可。
总复杂度 O ( n l o g n l o g ( a i ) ) O(nlognlog(a_i)) O(nlognlog(ai))。勉强能满足这题的时限。

反思

在队伍里,我是做DP的,但是比赛时没有想出解法。
第一个二分提出之后,我没有注意到题目的时限,错误地认为需要 O ( n ) O(n) O(n)检验,思考方向全在贪心和单调队列优化上面。

1006 Fansblog

题意

给出一个质数 P   ( 1 0 10 ≤ P ≤ 1 0 14 ) P\ (10^{10}\le P\le10^{14}) P (1010P1014),小于 P P P的质数中最大的为 Q Q Q,求 Q !   m o d   P Q!\ mod\ P Q! mod P

题解

P − 1 P-1 P1开始枚举,用Miller-Robin素性测试,因为素数较为密集,可以很快枚举出 Q Q Q
根据威尔逊定理可知,当 P P P为质数时, ( P − 1 ) ! ≡ − 1   ( m o d   P ) (P-1)! \equiv -1\ (mod\ P) (P1)!1 (mod P),所以一路用逆元做除法,将 ( P − 1 ) ! (P-1)! (P1)!除成 Q ! Q! Q!即可,因为模数很大,注意可能溢出的地方用__int128或者使用快速乘。

1007 Find the answer

题意

给出一个长为 n   ( n ≤ 2 × 1 0 5 ) n\ (n\le2\times 10^5) n (n2×105)的数列 W i W_i Wi和数字 m   ( m ≤ 1 0 9 ) m\ (m\le10^9) m (m109),要求输出 n n n个数字,第 i i i个数字表示在前 i − 1 i-1 i1个数字中至少要把多少个 W i W_i Wi变成 0 0 0才能使得 ∑ j = 1 i W j   ≤ m \sum_{j=1}^{i}Wj\ \le m j=1iWj m

题解

离散化后,每次 i i i都尽量取最小的,取得越多越好,那么在线段树上做个二分即可。
复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

1008 Game

题意

给出 n   ( n ≤ 1 0 5 ) n\ (n\le 10^5) n (n105)个排列好的石堆 a i   ( a i ≤ 1 0 6 ) a_i\ (a_i\le 10^6) ai (ai106),先手会选择一个合法区间 [ L , R ] [L,R] [L,R] ,接着后手会在这个区间内再选择一个子区间 [ l , r ]   ( L ≤ l ≤ r ≤ R ) [l,r]\ (L\le l\le r\le R) [l,r] (LlrR),两人开始在这个子区间内进行Nim游戏。
操作一给出先手选择的 L , R L,R L,R,问先手此时是否必胜。
操作二是交换 P O S POS POS P O S + 1 POS+1 POS+1,不做回答。

题解

三维莫队+线段树。
首先,这些询问都是可以离线处理的,但是查找夹杂着修改,那么莫队需要加一维时间维度。
对于后手来说,他只用在 [ L , R ] [L,R] [L,R]中找到两个前缀异或和相等的位置即可。我们要做的无非是判断当前区间内是否存在相等即可,因为石堆数量不大,可以直接开个数组弄,即使数量大也可以离散化。
综上,总复杂度是三维莫队的复杂度 O ( n 5 3 ) O(n^{\frac{5}{3}}) O(n35)

1009 K Subsequence

题意

给出一个长为 n   ( n ≤ 2 × 1 0 3 ) n\ (n\le2\times 10^3) n (n2×103)的数列,要求取出 k   ( k ≤ 10 ) k\ (k\le10) k (k10)个不重叠的不下降子序列,使得所有取出来的数字和最大。

题解

谁能想到费用流就过了呢= =
超级源点向每个数字连费用为0的边。每个数字拆点,流量为1,费用为数字大小。从前往后,小的数字向大的数字连无费用的边。每个数字的出点向超级汇点连费用为0的边。拆超级源点或汇点,限流 k k k,保证取出序列的个数。
其实也不难想到,因为流量极小,做不了几次增广就结束了,复杂度反而出在最短路上,SPFA在稠密图上表现不好,Dijkstra才能过。(稍微手模了一下,貌似这种建图巨卡SPFA= =)。
总体复杂度大致为 O ( 10 n l o g ( n ) ) O(10nlog(n)) O(10nlog(n))

1010 Sindar’s Art Exhibition

题意

给出一颗 n   ( n ≤ 1 0 5 ) n\ (n\le10^5) n (n105)的个节点的树,每个节点都有两个值 f i ,   y i f_i,\ yi fi, yi
操作一,给出起点 s s s 和终点 t t t 以及初始值 x x x,每经过一个点,获得收益 f i ⋅ x f_i\cdot x fix,,之后 x x x减去 y i y_i yi,求总收益。
操作二,修改单点的 f i f_i fi

题解

树链剖分。剖分后转换为区间问题,之后用线段树维护,然后就是我队友发挥的 t i m e time time了。

1011 Squrirrel

题意

给出一棵有 n   ( n ≤ 2 × 1 0 5 ) n\ (n\le2\times 10^5) n (n2×105)个节点的带有边权的树,你可以使一条边的权值变成 0 0 0,之后在树上找到一个点,使得这个点到树上每个点的最远距离最小。

题解

不难想到是树形DP,但是这题的状态设置和状态转移都出奇地复杂。
下面分享一下我的写法,基于HDU给的题解,实现上稍微添加了一些自己的想法。
M a x 1 [ i ] [ j ] Max1[i][j] Max1[i][j]表示以 i i i 为根的子树中,离节点 i i i j j j 远的距离是多少,这里的排名只需要维护前3大即可,但是要求来自 i i i 的不同儿子。
M a x 2 [ i ] [ j ] Max2[i][j] Max2[i][j]表示 M a x 1 Max1 Max1中,第 j j j大的子树中,一条边归零后,最大距离是多少,这个只需要维护前2大。

维护 M a x 1 Max1 Max1不难,但是要注意保存来自哪一个儿子,方便后面分情况做 f 1 , f 2 f1,f2 f1,f2
M a x 2 Max2 Max2的维护也很简单,因为已经指定好了子树。分两个方案取 m i n min min,一个是删除当前边,儿子节点保留完整子树的最远距离;一个是保留当前边,子树的最远距离从儿子节点的 M a x 2 Max2 Max2转移过来。

f 1 , f 2 f1,f2 f1,f2分别表示搜索到当前点时,以它为整个树的根,原来父节点的子树中,不归零和归零的最远距离,这两个值都要在父节点向子节点搜索时算出。
f 1 , f 2 f1,f2 f1,f2的维护中,从父节点转移到儿子节点时,要注意当前是否转移到第一远子树或者第二远子树,这两个子树的 f 1 , f 2 f1,f2 f1,f2计算方法略有不同。
令当前点为 x x x,与儿子连边的长度为 w i w_i wi,想转移给儿子的为 F 1 , F 2 F1,F2 F1,F2
F 1 = m a x ( f 1 , M a x [ x ] [ 1 ] ) + w i F1 = max(f1,Max[x][1]) + w_i F1=max(f1,Max[x][1])+wi
F 2 F2 F2懒得写等式了,分三个方案:
1、归零当前连边,在 f 1 f1 f1以及其他子树 M a x 1 [ x ] Max1[x] Max1[x]中取最远距离。
2、在父树上归零,在 f 2 f2 f2以及其他子树 M a x 1 [ x ] Max1[x] Max1[x]中取最远距离再加上当前边。
3、在其他子树中归零,在 f 1 f1 f1以及其他子树 M a x 2 [ x ] Max2[x] Max2[x]中取最远距离。
无论是转移给哪个子树,采取的方案都相同,但是区别在于 M a x 1 Max1 Max1中,你只能选取其他子树的方案,这也是为什么要记录前三大的数据。

答案当然就是在父树上归零和子树上归零取个最优啦,第一问的选取一个字典序最小的点也可以轻松维护。
总体复杂度 O ( n ) O(n) O(n),但是因为是维护前三大,而且转移方案多,常数会非常大。

补题

  • 1002
  • 1004
  • 1006
  • 1007
  • 1008
  • 1009
  • 1010
  • 1011

读题

1001
1003
1005

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值