2017.8.16 总结

来源:互联网 发布:mac系统语言改成英文 编辑:程序博客网 时间:2024/06/05 00:50

今天的题…不简单…不过还好出题人良心,给了一份豪华加长版的题面和一份精简版的题面(结果可想而知,全部人都去看精简版了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,每经过一个点更新mindsumw,但没想到我打萎了…结果最后这题爆零了。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,pl表示在当前结点线段树所在区间最左边的花精所在的位置,r表示最右边的花精所在的位置。mid表示在这个小区间[l,r]中的两只花精之间的最长距离除以2后的值。p表示取mid时所在的紧邻的两只花精的中间位置,也就是在[l,r]中的答案值。
对于1询问:访问线段树的第一个节点,我们比较l1,nr,mid的值哪个更大,就选哪个,它们的答案依次是1,n,p。假设我们求得的位置是pos[x]。然后访问[pos[x],pos[x]]所在的线段树的叶子节点,初始化它的值,然后回溯,进行合并。对于tr[x].ltr[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]]删除,然后回溯时,再做一次合并操作。

原创粉丝点击