zoukankan      html  css  js  c++  java
  • BUPT训练随笔(round 5)

    BUPT T5

    目前已掌握:ABDEFHJL

    A:一颗n个点的有根树,每个点有个权值ai,你能获得这个权值ai当且仅当这个点没有被摄像头覆盖,给定m个摄像头,每个摄像头可以覆盖这个点子树内深度距离这个摄像头不超过k的点,可以花费ci的代价拆除这个摄像头。

    思路:赛中是我开的题,想了下感觉是个最小割,然后并不会优化就跑了。比赛到最后40分钟回到这道题。队友说了大概思路。想了个map来维护的方法,但是发现map的指针运用的极其不熟练,之后比赛之前要仔细复习auto以及string的用法。(不会编代码实在太难了呜呜呜)方法如下,我们发现最小割转化为最大流,那么显然我们考虑每次跑一个点的时候,每加入一个摄像头,增广的路径显然是节点深度>c的ai增广过来的。那么可以考虑开个map维护目前节点深度为d的点还有多少可以增广的流量,每次暴力枚举转移即可。赛中队友说可以用长链剖分启发式合并。赛后仔细研究了一下复杂度。每个map的大小显然是长链的长度。一个map只会作为一个短链的开头合并到另一个长链的map里,且只会合并一次,所以合并的总复杂度就是所有长链的长度和,即为n.所以总复杂度是nlogn

    B:随机生成一个1-n的排列,每次随机激活一个位置上的值,要你维护n次的添加的LIS的长度。

    思路:我们发现排列完全随机。所以必然是用暴力做法来玄学水过。我们发现正着做一来无法直接维护LIS,二来没法做到优化复杂度。但是倒着做,即删除数,发现可以有玄学的地方。我们判断删除的数是不是在LIS内,如果不在LIS内的话就直接继承上一次的答案,如果在LIS内就暴力重构一遍LIS。然后通过了本题。赛后通过查询题解得知长度为n的随机排列的LIS长度期望为根号n,所以期望重构的次数约为根号n,期望复杂度为n根号nlogn

    D:有n个任务,每个任务由A完成需要时间ai,由B完成需要时间bi,A,B做任务完全独立,设A完成任务总时间为X,B完成任务总时间为Y,要求每次给出一个任务后最小化max(X,Y)。

    思路:这题赛中写吐了。先考虑贪心,每个任务都给用时较短的那个队伍做。但是显然这样子最终A,B完成任务的时间会有差值。而答案必然X=Y,所以我们要让用时比较多的那个人“匀”一些任务给用时较少的那个人。我们继续贪心,设用时较多的人为A,用时较少的人为B。那么我们要找的任务显然bi/ai越接近1越好。所以我们可以预先对bi/ai排序处理,然后线段树维护区间和,这样子就可以用线段树二分找到最优的替换代价了。注意到如果ai=bi要特殊讨论,因为这时候的时间是可以任意分配的。或者预处理时默认给ai,B的线段树中插入也是可以的。这题赛中手写了分数类,但实际上一开始的想法是简单的线段树维护区间和最后的步骤单独处理分数,之后有时间再写一遍。(待填坑)

    E:二维平面上有n个点,每个点有权值。要你找到一个矩形,使得矩形内点的权值和最大。

    思路:简单的线段树+扫描线的题,送分。

    F:题意过难描述.jpg

    思路: 队友做的。发现一个特殊的东西就是2<=ki<=5,那么意味着lcm=60,可以暴力枚举xe,ye的余数,然后又发现这个绝对值比较烦人,可以暴力拆开abs,那么n个点最多把整个区间分为(n+1)^2个块,对于每个块再O(n)check,复杂度就是60^2*n^3,可以通过本题(感觉要我自己写起来不一定很容易,之后补)

    H:同样题意很难描述.jpg

    思路:队友做的。赛后发现f(n,m)与n的差值实际上不会超过1000(可以通过打表获得,我也不知道队友怎么想到的 队友tql.jpg)然后就可以枚举f(n,m)check答案就好了。

    J:一颗树,每个点有权值,要你选出一个联通块使得联通块内权值的wi的乘积不超过m,求方案数,n=2000,m=1e6。

    思路:首先想法自然是背包了。f[i][j]表示取了i个点,乘积为j,复杂度n^2m,直接爆炸。先考虑优化这个n^2,那就加个点分治好了,因为统计的是联通块,点分治也没有什么特殊的需要对上一级的ans容斥的部分。复杂度变为nlognm,很容易会想到将m优化成根号m,但是怎么优化是个关键。发现我们对于大于根号m的可以表示为还能往里面存多少东西的形式。因为我们一个数x,当前还能乘上的数不能超过[m/x]下取整,又因为[m/ij]=[m/i]/j,所以就可以分两个DP转移,复杂度就是nlognsqrt(m)

    L:给定一个n个点的小根堆,A,B每次可以取出一个没有儿子存在的节点,并将该节点删除。A,B都希望权值最大,求最终A,B获得的权值。

    思路:赛中看题看了好久。后来才发现是个小根堆的形式。暴力做法就是把没有儿子的节点丢到pq里,然后每次暴力拿节点。但是赛中写的时候觉得很麻烦(实际上是pq忘记怎么自定义写cmp了,我知道我菜了呜呜呜),发现可以直接对于n个点排序后从大到小直接取。为什么呢?因为每次取这个节点的时候这个节点都是当前最大的节点,显然不可能有儿子。所以这个方案成立。

  • 相关阅读:
    前序中序输出后序
    Blah数集
    中缀表达式转后缀表达式 (栈)
    1357:车厢调度 (栈)
    最长公共上升子序列 (LIS+LCS+记录)
    1481:Maximum sum (前缀和+dp)
    8464:股票买卖
    7627:鸡蛋的硬度
    2989:糖果
    U33405 纽约 (二分)
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/13649941.html
Copyright © 2011-2022 走看看