zoukankan      html  css  js  c++  java
  • 2019 Moscow Workshop 题解

    day1

    【A√,D√,H,J,K,L,M】

      水题;猥琐题。

    【B√】

      题意:有一个 (w imes h) 的桌面,上面有 (N(leq 11)) 个球,每个球有一个半径 (r)。现在 (1) 号球以 ((vx,vy)) 的方向前进,遇到桌的边界会完全弹性碰撞。问 (10000) 个单位长度内,它先撞到别的哪个球。
      题解:看上去要圆与圆求交。一个经典的处理方式是:可以将关键的圆看成点,别的图形相应地做变化即可。在这里,桌面边界会往里缩,其他圆的半径会增加 (r)。处理 (1) 号球的碰撞时,只需处理点的反射。

    【C√】

      题意:对于 (1 leq A leq B leq 10^{18}),记 (k_i)(A sim B) 数字中二进制第 (i) 位是 (1) 的数字个数。现在给出 (k_i (i leq 63)),判断 ((A,B)) 的有解性,如有唯一解同时给出解。
      题解:从大到小考虑 (k_i)。每次考察 ([A,B]) 是否跨越了 (2^i) 这条分割线。如果没有跨越,那么我们知道 ([A,B]) 是在 ([2^i,...]) 区间里一个长度为 (k_i) 的区间,继续递归下去求解。如果跨越了,根据 (k_i),我们可以直接定位出 (B) 的值((A) 也可以通过二分来确定);注意上层递归下来时,可能有 AB 长度要求,必须同时符合才行。

    【E√】

      题意:给出一个最多 (1000) 项的多项式 (F(x)=sum a_i x^{b_i}),其中 (a_i leq 10^{15},b_i leq 10^9)。已知 (F(x)=F'(x)=0),求符合要求的最小正整数解 (x) 或输出无解。
      题解:由题意可证,(x^2 | a_k),其中 (k) 是次数最小的非零项。快速分解 (a_k) 后,直接枚举所有符合要求的 (x) 即可。check 时,可以给出一些模域;多个模域下为 (0) 可视为答案为 (0)。快速分解时,可以只枚举到 (10^5),剩下的质因子只可能是 (P,PQ,P^2),而只有第三者才有意义。

    【F√】

      题意:初始时有一个三个点的二叉树,“剪贴板”上也是这棵树。每次可以选择一个叶子,将其替换为剪贴板上的内容。每步操作完成后,可以选择将整棵树放入剪切板(不消耗步数)。给出一棵 (N(leq 1000)) 个点的二叉树,问可以最少几步变成它。
      题解:考虑最后一次复制后的图形。如果枚举了它的大小 (k),我们可以知道它的具体形状,也可以通过树哈希在 (O(N)) 的时间里,判断它是否可能。还会发现一个性质时,对于这个图形之前的小图形,因为能拼成这个,一定也能拼成总体。所以首先,我们可以枚举所有 (N-1) 的约数 (k-1),check 一遍以 (k) 为模板是否可行。如果枚举了最后的图形,我们要知道从初始开始最少几步到它,这可以通过对所有合法的约数做一遍预处理DP后得到。复杂度为 (O(K^2+NK))(K)(N) 的约数个数。

    【G】

      连通性DP。

    【I√】

      题意:有 (R(leq 128)) 行格子,每行 (C(leq 16)) 个。给出 (R) 个长度不超过 (C) 的字符串,将它们依次填在每一行,使得字符串字符的相对顺序保持不变(有些位置为留空)。定义一个有字符的格子的价值为:其上下左右和它一样的格子个数。求可能的最大的总价值。
      题解:很容易想到按行转移,每行最多会有 (C_{16}^8) 中状态。看上去状态数不多,但是显然不能支持平方的转移。比赛的时候想到了各种优化转移的方法,甚至要利用 trie,但是效果都不好。
      其实只要按格子一格一格转移(类似于轮廓线DP),这种表示方法也支持快速算代价,复杂度就是 (RC2^C)

    day2

    【A√,B,G,J,K】

      水题/模拟题;待补

    【C√】

      题意:给出平面上 (N(leq 100)) 个点,没有三点共线的情况。要画 (lceil frac{n}{2} ceil) 条直线将平面划成一些区域,使每个点仅属于一个区域。
      题解:先找到任意一条直线,将点集划成差最多为 (1) 的两部分。每次操作时,左右剩下的点各做一个凸包,取凸包的上(同侧)公切线,将其稍稍向下平移,即可做出一条将这两个点都分开的直线。每次删掉两个点继续操作,总复杂度为 (O(N^2))
      如何求两个凸包的公切线?。左右凸包各选择一个点,每次固定一个点 (A),如果 (AB) 和凸包 (b) 在顶点 (B) 外也有交,就把 (B) 继续往一侧移动。交替迭代,一定是向某条公切线靠近的。细致点实现,复杂度 (O(N))

    【D√】

      题意:求 (N) 个点的 每个连通块最多只有一个环的 带标号图的个数。
      题解:带标号无根树个数是 (N^{N-2}),考虑如何计算带标号基环树的个数。假设一共有 (N) 个点,环长是 (M)。对除环以外的 (N-M) 个点做 (prufer) 序列。该序列最后一个点必须是环上的点(因为做到的最后一个点的父亲必然在环上),其他随意。所以方案数是 (M imes N^{N-M-1})。再乘上 (frac{(M-1)!}{2} imes C_{N}^M) 即为 (N) 个点环长为 (M) 的带标号基环树个数了。最后做一遍背包即可得到答案。

    【F√】

      题意:有三只怪兽,攻击为 (A_i(leq 10^9)),血量为 (B_i(B_1 leq 10^{18},B_2,B_3 leq 100))。每轮开始时,所有活着的怪兽对你造成等同于它们攻击力和的伤害。第 (i) 轮时,你可以选择一只怪兽,对其造成 (i) 点伤害。怪兽血量非正时死亡。问打完所有怪兽后最少受到多少的伤害。
      题解:假设每轮都在打第一只怪兽。我们可能会在某几轮,“抽空”去打另外两只。设 (f_{i,j,k}) 表示到了前 (i) 轮,二三两只怪兽分别受到了 (j,k) 点伤害时,我们受到的最小伤害。注意这种表示下,如果 (k geq B_2)(j leq B_3) 也是有意义的,因为我们要根据 (i,j,k) 算出,我们已经对第一只怪兽造成了多少伤害了;这样也可以快速算出转移时我们每轮受到的伤害和。
      当超过 (102) 轮后,另外两只怪兽要不已经死了,要不被留在最后再攻击。

    【H√】

      题意:给出两棵 (N(leq 10^5)) 个点的带边权的树。求 (sum_{i,j} Ad_{i,j} imes Bd_{i,j} mod 10^9+7)。其中 (d_{i,j}) 表示 (i sim j) 的距离和。
      题解:考虑对第一棵树进行点分,每次计算经过分治中心 (x) 的所有 (Ad_{i,j}) 产生的贡献。将 (Ad_{i,j}) 拆成 (Ad_{i,x})(Ad_{j,x}),每个可以分开独立算。固定一棵子树,以及子树里的一个点 (u),对于所有 ((u,v))(v) 在子树外),要计算 (B) 树中 (d_{u,v}) 的和。为了方便,可以先计算所有 (pair) 的距离和,再容斥地减掉 ((u,v)) 都在子树内部的方案数。
      可以在 (B) 树上建出 (A) 的虚树,两遍 (dp) 求出距离和。也可以先构建一棵 (B) 的点分树,快速求一个点到一个点集的距离和。
      常数较大,可以考虑一些优化。比如,容斥过程中,没必要直接在当前层减掉子树的方案(因为这样要在虚树或者点分树里重新插入子树里的所有点)。到了下一层,本来就会有插满整棵树的过程,我们可以到下一层时再减掉。
      听说 (claris)(O(log N)) 做法。第一次学会了边分。可是还没领悟到他的做法。嘤嘤嘤……

    day3

    【B,E,H,J】

      猥琐题。

    【A√】

      题意:有 (N(leq 10^6))根平行的轨道,共有 (M(leq 10^6)) 横向的短棒支在一些相邻轨道上。当球从某根木棒下落时,一旦碰到短棒,就会滚到相邻轨道,并继续下落。给出初始时所有短棒的高度(保证互不相同)以及 (Q(leq 10^6)) 个操作,每次删掉某根木棒,或询问从轨道 (x) 下落的球最终会落到哪个轨道。
      题解:这个模型之前好像遇到过一次了……将木棒两段的点视作关键点,连同每根轨道初始的 (N) 个点。根据下落规律,在这些点之间连边,容易发现连成的是一条条链。更神奇的是,每当删掉某根木棒的时候,相当于将两条链在特定位置交换尾部。我们可以直接用 (splay) 来维护链,(splay)(key) 就是链的深度。询问时直接查询最深的点即可。时间复杂度 (O(N log N))

    【C√】

      题意:用 (M(leq 100)) 个模式串 ((|S| leq 100)) 消一个长度为 (N(leq 100)) 的母串。每次消掉匹配上的位置,剩下的串前后接起来。问最少消几次能消光。
      题解:以前做过一个模式串的题。设 (g_{i,j}) 表示消完 (i sim j) 的最少步数,(f_{i,j,k,l}) 表示消 (A_i sim A_j),消完后还剩下第 (k) 个串长度为 (l) 的前缀 的最少步数。转移时枚举后面消光的一段 (g_{j+1,t}),转移到 (f_{i,t,k,l+1})。复杂度 (O(N^5))

    【D√】

      题意:总共有 (N(leq 8)) 种牌,给出 (N imes N) 的大小关系矩阵。甲有 (n_1) 张牌,乙有 (n_2) 张牌,两人博弈,每次双方出一张牌。若牌有大小之分,小牌被丢弃;如果牌一样,都被丢弃。赢的人得 (1) 分,输的人不得分,平局各得 (0.5) 分。双方都想使自己分数高,问最终分数的期望。
      题解:因为执最优策略,(N) 又比较小,肯定要子集 (DP)。现在问题是,给出目前甲乙的牌集(假设更小的集合我们已经 (DP) 过了),如何确定甲乙出牌规律。这个转移可以抽象为一个矩阵:甲选一行,乙选一列,甲想使数值最大,乙想使数值最小,求期望。
      注意到这是双人有限零和博弈,是纳什均衡的基本模型。纳什均衡:没有玩家可以从单方面改变他或她的策略中获益。一个推论:如果乙的策略未知,甲采用某种纳什均衡混合策略,能使可能的最大损失最小。相关资料
      由这个推论,设 (p_i) 表示甲对于每一行选的概率,我们可以直接得到矩阵模型里期望值 (w) 的线性规划方程。

    [max(w) \ s.t. sum p_i a_{i,j} geq w,forall j in [1,m] \ sum p_i=1 ]

      一个有趣的事情:如果我们根据乙来列方程,显然最终求得的 (w) 是一样的,而新方程正好是原方程的对偶式:侧面映证了线性规划对偶转化的正确性。
      单纯形来解有种大材小用的感觉?事实上,如果满足 (p_i >0,q_j>0),可以直接用高斯消元解出甲的策略 (p_i)(乙也同理)。

    [sum p_i a_{i,1} = sum p_i a_{i,2} = dots sum p_i a_{i,j},forall q_{j}>0 \ sum p_i = 1 ]

      为什么在保证 (>0) 的情况下,(geq w) 就能变成 (=w) 了呢?感性地想一下,每一个 (p_i)(>0),如果有一个 (sum) 偏大,我总能通过加加减减 (p_i),使 (w) 偏大。但是如果某个 (p_i=0) 了,继续往下减是不符合限制的。
      在一般情况下,(p_i)(q_j) 有可能是 (0)。所以我们要枚举它们的一个非零的集合,才可以用高斯消元解出它们(我们总能证明,一定存在一种纳什均衡,使得不为 (0) 的行和列一样多,这样就可以安心消啦)。每解出一组解,记得带回去检查:所有 (q_j=0)(j)(sum p_i a_{i,j}) 不能超过 (q_j >0)

    【F√】

      题意:给出一个长方形的三条边 (a,b,c)。要从一个顶点出发,走到面上的任意一个点,问最短距离最大能是多少。
      题解:开场 (WA) 了一片……首先,最远的点并不是对角的那个顶点。如果我们要从 ((0,0,0)) 走到面上的一个点 ((x,y,z)),分类讨论一下是有四种可能的路径(其中有两条必然存在,有两条两者可能不存在),最短距离是它们的 (min)。因为是求 (min) 的最大值,可能从对角的顶点往边上挪一挪,会使原最来的 (min) 变大一些,使得答案变优。我最后暴力列出这个求 (min) 的式子,无脑写了一个模拟退火。

    【G√】

      题意:数轴上有 (N(leq 5000)) 个点 (a_i)。设置 (K(leq 5000))(b_i),使得 (sum min_{1 leq j leq K} |a_i-b_j|) 最小。
      题解:其实肯定是按顺序划过去,每次放置在一个集合的中位数上。比赛时用 (O(N log N log V))(zyb) 二分卡过去的。二分新增集合的代价 (C) 后,(f_i=min(f_j+cost(j+1,i)+C))。这个东西有决策单调性,所以采用二分和栈来维护。
      类似 (f_{i,j}) 表示前 (i) 个点,选了 (j) 个集合 这种 (DP) 模型也存在一种四边形不等式的优化。脑补一下就有 (opt_{i-1,j} leq opt_{i,j} leq opt_{i,j+1})。按 (i) 升序 (j) 降序的顺序做即可。复杂度 (O(NK))

    【I√】

      题意:考虑模质数 (p) 域下的多项式 (f(x)=x^n+a_{n-1}x^{n-1}+dots+a_1x+a_0) 构成的集合 (Z_n)。问有多少个元素是不可约的,即不存在一个多项式 (g in Z_k),使得 (f)(g)(0)。答案对 (m) 取模。(m,p,n leq 10^9)
      题解:有重要性质:(x^{p^n} -x=prod Q(x)),其中 (Q(x)) 是所有集合 (Z_k) 满足 (k|N) 的并。所以直接套莫比乌斯反演即可。

    day4

    【A√,E√,B,C】

      水题;猥琐题。

    【D√】

      题意:有 (N(leq 10^5)) 个人,每个人头上会有一顶非黑即白的帽子。再给出 (M) 组有向关系 ((u,v)),表示 (u) 能看到 (v) 头上的帽子。问是否存在一种猜自己头上帽子的策略,不管帽子颜色如何分配,至少有一个人能猜到自己头上帽子的颜色。
      题解:一个人猜自己帽子的策略无非是 (f_i(p_{i,1},p_{i,2} dots))(p_{i,j}) 是它看到的帽子颜色。
      如果图中存在至少一个环,必然有解。比如三元环,颜色分别是 (a,b,c)。第一个人可以猜自己是 (b),第二个人猜自己是 (c)。如果要让它们都猜错,则 必须满足 (a=b=c)。这时候第三个人猜自己是 (~a),则不存在一组全猜错的分配方案。
      如果图中没环,你总能以拓扑序的方式去分配帽子颜色,使得所有人都猜错。

    【F√】

      题意:定义一个长度为 (k) 的串 (S) 的回文度是满足 (0 leq i < k-i-1)(S_i=S_{k-1-i})(i) 的个数。给出一个长度为 (N(leq 123456)) 的串,求其所有子序列的回文度之和。
      题解:直接枚举两个位置 ((i,j) S_i=S_j),计算它们出现的次数。它们中间的串不造成任何影响,所以方案是 $sum limits_k inom{i-1}{k} inom{n-j}{k} $。将右边的组合数写成 (inom{n-j}{n-j-k}),这个求和式直接等于 (inom{i-1+n-j}{n-j})。现在变成了卷积式,直接对于每一种字符 (NTT) 即可。

    【G√】

      题意:维护一个 (N(leq 10^6)) 个数的数组和 (Q(leq 10^6)) 个操作:① 将第 (x) 个数换成 (y);② 给出一个区间 ((l,r)) 和一个常数 (k),且 (k,k+1,dots,k+m) 是这个区间的子序列,问 (m) 最大能是多少。
     题解:一个很直接的想法是,对于每一个数 (a_i),记录下一个值为 (a_i+1) 的数组下标。这样可以用 (LCT) 来维护这些森林。但是每次修改数字的时候,涉及到的点可能会很多。
     在原来的基础上改进一下:维护每一个数 (a_i) 后面第一个出现的 (a_i)(a_i+1)。为了方便维护答案,可以把后者的点权设为 (1),询问时求个和即可。这样修改时只涉及 (O(1)) 个数了。

  • 相关阅读:
    【转】Maven多模块项目构建
    【转】vue和springboot项目使用nginx配置,并配置跨域
    关于URL与URI
    C#将16位二进制转换为有符号数
    WPF中 datagird日期列格式
    记录一个困扰了我两个周的Windows网络问题
    基于企业上下级关系的组织机构体系数据模型设计
    WPF简介
    和尚挖井故事给程序员的启示!
    看八个笑话故事 悟八个人生道理
  • 原文地址:https://www.cnblogs.com/jiangshibiao/p/10527659.html
Copyright © 2011-2022 走看看