2017.8.16 总结

今天的题…不简单…不过还好出题人良心,给了一份豪华加长版的题面和一份精简版的题面(结果可想而知,全部人都去看精简版了2333~)。
P.S.以下我都精简题意(懒得多打字2333~)。

T1

题意:(原题意在前面讲了一大堆…)实际上就是给你一个 n×m 的点阵(即给你一个 n×m 的矩形,包含 (1,1) (n,m) 所有坐标的点),让你求其中任意两个点构成的不重合的直线有几条。 (n,m4000,T10000)

思路:当时刚看到这题,我还以为要用欧拉函数啊啥的(雾),实际并不用…但我没啥思路,想打个 O(n4) 暴力吧,分太少。后来推着推着发现一个方法:
显然的是平行于坐标轴的直线只有 n+m 条,之后任意一条不垂直于坐标轴的直线将斜率取反都能得到相应的另一条直线。所以可以只计算斜率为正且不平行于坐标轴的直线。
然后就可以枚举向量 (a,b) ,显然 gcd(a,b)=1 。定义一个点 (x,y) 的前驱为 (xa,yb) ,后继为 (x+a,y+b) ,则直线的数量满足“它本身以及它的前驱在点阵内而它的后继不在点阵内”的点的数量。
经过一顿瞎搞(雾),我们可以搞出这么个式子来计算直线向量 (a,b) 的直线的条数:
(na)×(mb)max(n2a,0)×max(m2b,0)
所以这个问题就变成了计算如下式子:
n1a=1m1b=1[gcd(a,b)==1]((na)×(mb)max(n2a,0)×max(m2b,0))
直接暴力就有60了。

题解:实际上,就把前面的这个式子进行 O(n2) 预处理二维前缀和,之后 O(1) 询问就行了QAQ…(当时竟然没想到啊啊啊)

T2

题意:给你一个由 n 个点构成的一颗树,每个节点都有一个权值di,每条树边也都有一个权值 wi ,对于树上的一条路径,令路上所有节点权值 di 的最小值为 mind ,路径上所有边权值 wi 之和为 sumw ,则该条路径的权值为 mind×sumw
P.S.路径的起点和终点可以使任意点。
求所有路径中权值最大的那一条路径的权值是多少。 (T10,n100000,di1e9,1u,vn,wi1e9)

思路:我之前的思路是直接打一发暴力,枚举两个点,然后暴力向上跳找 LCA ,每经过一个点更新 mind sumw ,但没想到我打萎了…结果最后这题爆零了。 QAQ

题解:有两种做法:
1 点分治。点分治时,我们每次选取一个中心,先统计经过中心的直径最大值,然后删掉中心,递归处理其他子树。统计过中心的路径的最大值,我们以中心为根 DFS 一遍,(P.S.注意这里路径的两个端点不能在同一子树内)。最后我们把路径按子树,然后点权排序以后更新路径按子树分类的最大值和次大值,之和与当前点权的乘积就是答案。
2 并查集。将所有点按照权值从大到小排序,对于将当前点和与其相连的所有点依次合并到一个集合中。并查集需要维护当前集合中最长路径长度和对应的两个端点。在合并两个集合后,最终集合的最长路一定只有两种情况:一类是其中一个集合的最长路,一共有两种;一类是由两个集合的最长路径的端点互相连接而成,一共 2×2=4 种。需要求 LCA 来预处理两点在树上的距离,离线处理。每次合并并查集后用当前点的权值乘最长路的总长度来更新答案就行了。

T3

题意:一只花精喜欢住在离其他花精最远的玫瑰花里,在花园中有一排玫瑰花,从左到右编为 1n 。初始时全部是空的。有若干只花精,进出玫瑰花共 m 次。对于每只进入玫瑰花的花精,与其他花精距离最小值最大的一朵玫瑰花,若有若干朵符合条件,选最左边的一朵。现在给你花精们进出的序列,依次输出每只花精的玫瑰花的编号。一朵玫瑰花只能容纳一只花精。(n,m200000)

思路:没啥说的233,当时我就打了个暴力拿了30,就是用一个bool数组记录每朵玫瑰花是否已经被占用,然后建立两个数组,一个用来维护每朵玫瑰花到那些已经被占用的玫瑰花的距离,之后乱搞一通就行了233。

题解:考虑用线段树。首先我们对区间 [1...n] 建立一颗线段树。对于每一个节点维护4个值:分别是 l,r,mid,p l 表示在当前结点线段树所在区间最左边的花精所在的位置,r表示最右边的花精所在的位置。 mid 表示在这个小区间 [l,r] 中的两只花精之间的最长距离除以 2 后的值。p表示取 mid 时所在的紧邻的两只花精的中间位置,也就是在 [l,r] 中的答案值。
对于 1 询问:访问线段树的第一个节点,我们比较l1,nr,mid的值哪个更大,就选哪个,它们的答案依次是 1,n,p 。假设我们求得的位置是 pos[x] 。然后访问 [pos[x],pos[x]] 所在的线段树的叶子节点,初始化它的值,然后回溯,进行合并。对于 tr[x].l tr[x].r 可以通过两个儿子的 l,r 信息得出。对于 tr[x].mid 值,首先在左右儿子的 mid 值中去一个最大的值。其次考虑一种情况,就是夹在两个线段之间的距离,可以通过 (tr[x+x+1].ltr[x+x].r)÷2 的值得出再与 mid 进行比较,然后 p 就随着mid的值得更新而更新。
对于 2 询问:访问询问花精所在的位置,直接将它的叶子节点[pos[x],pos[x]]删除,然后回溯时,再做一次合并操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值