日常训练.jpg

TodoList

SAM

SteinerTree

2018/3/26


SRM600 Div1

250 枚举哪一位是个卜。

600 枚举回文列的集合,然后对行进行DP,\(dp[i][j]\)代表最前的i行与最后的i行中,有j行为回文的最小耗费。我们对第i行与第n-i+1行进行决策。

  • 两行都不回文:这个时候把列给凑对就好了&逐个施展

  • 两行有一个回文:把两行C多个22

  • 两行都回文:把两行拆成很多个22&逐个施展

900 欧拉公式,把直线一条一条的加入进去,然后计算交点个数,然后发现交点个数互质数对个数有关。

SRM601 Div1

250 题意杀?枚举一共拿了多少个水果,用桶来维护每袋水果最多拿几个苹果,最少拿几个苹果。

650 一脸懵逼的DP

  • 假算法1:\(dp[i][A][B]\): 考虑\(1~i\)这些数字,集合\(1\)的异或和为\(A\),集合\(2\)的异或和为\(B\),的情况有多少种。稳如gou的TLE

  • 假算法2:\(dp[i][Dt]\): 其中\(Dt=A-B\)\(Dt\)为一个三进制数字。

  • 真算法:枚举不相等的第一位,那么在这位上,A的异或和为0,B的异或和为1,在此位之前的位上,\(A的异或和\) \(Xor\) \(B的异或和 = 0\)

  • 优化:不相等的第一位后面可以放飞自我。

950 读不懂题,睡觉

2018/3/27


SRM602 Div1

250\(dp[52][2202]\)表示i场比赛后Rating为j最大的颜色变化。注意到Rating超过2200后必须掉分,所以第二维开到2200就够了。决策:上分 or 掉分。

550 注意到面积交的最大值 =$ Min(长) * Min(宽)$,我们先通过旋转保证“长<宽”,然后对所有矩形按长排序。我们不妨设最小的长出现在了A组中,然后我们枚举B组中最小的长。我们可以通过不等式来证明,保证B组的宽尽可能长时,A组的宽尽可能长时面积和取到最大。B组最长的宽可以用堆来维护。WA了一上午!卜。

1000 数学公式推倒题。待卜

SRM603 Div1

250 因为先手不能把所有度数为1的点放逐,所以答案 = Max{cost of node whose deg = 1}。迷之博弈,后手连操作都不å用操作游戏就结束了。囍

500 不难看出B可由A经过Shift得到,我们可以按照循环节对答案进行分类。令\(F(x)\)表示长度为x且最小循环节恰为x的串有多少个,\(F(x)\)可由简单的容斥求得。\(F(divisors\ of\ n)\)即为答案。

1000 一定要卜的题。神妙的战法。

做法:如果我们要凑X,那么答案为Sum of min(cnt_A[i], cnt_B[X-i])【很强的卷积既视感,然而FFT施展不开吖!】。注意到

min(A,B) = sum [k<=A & k<=B]
所以答案为满足cnt_A[p] >= k且cnt_B[q] >= k的三元组(p,q,k)个数。对于较小的k可以施展FFT,对于较大的k可以施展暴力。

2018/3/28


SRM604 Div1

Div2 1000\(dp[u][e][x]\)表示,在以\(u\)为根的子树放x只排骨龙,且Ban掉前\(e\)个儿子的子树的方案数。转移的时候枚举\(u\)的第\(e\)棵子树放几只排骨龙。

250 将x与y分别展开成平衡三进制。相同位上不能同为0,不能同非0。

500 NAN,待卜。

1000 战法:Infinity的条件:对于所有非0的方向向量\((dx, dy)\),都可以找到一堆点对\(P_{i}\), \(Q_{i}\),使得\(P_{i}Q_{i}\)平行于\((dx,dy)\),且长度在0的右邻域连续

SRM605 Div1

Div2 1000 假设比\(n\)大的数字全部施展完了,现在我们要施展n。与n匹配的数字必须在\([n+1,n+k]\)之间,我们可以对Unmatched的\([n+1,n+k]\)中的数字进行状压。不妨设这些unmatched的数字都出现在第一个数组中,我们的决策有两种

  • 把n放到第1个数组
  • 把n放到第2个数组

250 简单的贪心。

450 假设大于n的数字全部施展完了,现在我们施展n,那么与n匹配的数字一定在
\([n+k,M]\)之间。我们设计状态\(dp[n][g][mask]\),用g代表在Unmatched的数字里,有多少个\([n+k,M]\)在之间,同时用mask对\([n+1, n+k)\)之间的数字进行状压。决策同样有两种。

  • 和Unmatched的数字放在同一个数组里
  • 和Unmatched的数字放在不同的数组里

1000 不会啊!很痛苦

2018/3/29


三月的狮子真他喵好看!

施展了一场CF Gym,游戏体验囍狠了。

感觉自己是羊肉粉丝弱鸡 Import From Here

先写服辩!然后是睡觉。

  • Lucas不会,中国剩余定理不会。卜!
  • 你别挂机呀![比赛兴奋一点吖,去High,高兴,去玩,飞起来的那种感觉,懂吗?出自窃格拉瓦]
  • 对爆LongLong,double精度什么的直感很辣鸡。
  • 读题怠惰症,在队切的时候体现得特别明显 (我有杨利伟叔叔,我读个锤子题)

2018/3/29


睡了一天觉

2018/3/30


SRM 606

Div2 1000 枚举排列

Div1 250 一个数字可能合法的充要条件是:满足所有询问。 统计好每个数字满足几个询问即可。

Div1 450

两种情况

  • 出现最多的数字如果超过一半
  • 出现最多的数字没超过一半

Majority Vote Algorithm

Div1 1000 枚举三个点,三个点最多确定两个正方体。

2018/3/31


SRM 607

Div2 1000 不会,很狂躁

Div1 250 计算以每个位置为中心的贡献就好了,很基本。

Div1 475 不会,很痛苦。

Div1 1000 不会,很痛苦。

现在看见DP就想逃跑

2018/4/1


SRM 700

Div2 Lv.2 状压一下然后暴就OJBK了

Div2 Lv.3 可以类比括号匹配,括号能匹配上的一个必要条件是,前缀中的'('个数多于')'个数。我们可用\(dp[i][j]\)表示前\(i\)个人中有\(j\)个人吃鸡有几种方案。然后对第\(i+1\)个人是否吃鸡进行决策就好了。因为答案是考虑顺序的,所以最后的结果要乘上\(k!\)

Div1 Lv.1 如果这位选手是Leader那么答案为1,否则从后向前扫一遍,尝试着把这位选手丢进\(i\)号房间。并判断是否合法即可,合法条件就是楼上的那个必要条件。

Div1 Lv.2 先选出\(x\)只排骨龙,让他们射来射去,形成一个置换群。然后我们考虑剩下的\(n-x\)只排骨龙。当时YY的一个想法:“我萌首先从\(n-x\)只排骨龙里选出第1批排骨龙,拿着这些龙去射那x只龙,然后再从剩下的龙中选出第2批排骨龙,然后拿着这批龙去射第1批排骨龙,依次类推”。然后就陷入了\(O(n^3)\)的江局。其实不妨这样考虑,答案等于\(n\)个点搞出\(k\)棵有根树的方案数,然后题解厚颜无耻地给了一个公式\(kn^{n-1-k}\)

2018/4/2


SRM 699

Div2 Lv.2 这个东西有单调性,二分答案即可。

Div1 Lv.1 按位枚举,枚举这位上的1的个数的奇偶性,就可以求得所有不挂机的位置,如果矛盾,那就从挂机的位置施展1个1。

Div1 Lv.2 设当前的数字为\(x\),且有\(a[i]|x\),那么\(x\)的后继肯定是\(b[i]\)的倍数,如果\(t\)\(x\)的后继中,就稳了,否则还得奔波,我们设\(x\)的后继为\(y\),那么必须得存在\(j\)使得\(a[j]|y\),不然\(y\)出不去吖!所以满足要求的最小值为\(y=lcm(b[i],a[j])\)

Div1 Lv.3 预处理好以每个点为左上角的,边长大于\(x\)的最优的矩形,枚举正方形的交。待补

2018/4/9


Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)

D

维护每一层的位移。因为层数不会太多,所以单次查询复杂度为\(O(rank)\)

E

经典的路径统计问题。

我们考虑每个节点对答案的贡献。

对于\(u\)节点而言路径可分为3种

  • \(u\)的子树外面,到\(u\)的子树
  • \(u\)的子树,到\(u\)的子树
  • \(u\)的子树,到\(u\)的子树外面

F

本质上,是个LIS问题

两个做法

  • 拿着map开树状数组。
  • Big-Small战法,统计每个数字出现的次数,出现得比较多的用BIT维护,出现的比较少的暴力施展。

G

注意到最大的数字,不管从前往后看,还是从后往前看,都在最后一个位置。

我们先把n-1个数字分出A+B-2个环,然后选择A-1个环放在左边。

所以\(Ans = S(n-1,A+B-2) * C(A+B-2, A-1)\)

然后上NTT!(T▽T)

你个羊肉粉丝弱鸡快去学NTT啊!

斯特林数也快去学啊!

2018/10/11


Codeforces Beta Round #91 (Div. 1 Only)

A

暴力搜索出所有lucky数字。

B

  • 先模拟
  • 发现陷入了循环,就break出来,循环节一定为2

C

  • 这不就是传说中的康托展开吗?n个数的排列求第k大?求第k大的排列是啥?这种问题都可以得到施展,只需从高位到低位枚举,每位上的数字是确定好的。
  • 这个问题,因为k很小啦【对于阶乘来说】。所以n比较大的时候,我们只需考虑最后14位就好了。

D【待补】

E

  • 哇!首先我们可以看出lucky number不会很多。
  • 我们建线段树,维护区间内,\(nexLuck(x)-x\)的最小值\(mn\),以及这个最小值出现的次数\(cnt\),区间修改时,我们对区间加\(add\), 如果\(mn > add\),那么\(mn =mn-add\)然后打好懒惰标记即可,否则,我们递归地更新左儿子,右儿子。然后将左儿子右儿子的信息合并到当前节点。这样的递归会一直递归到\(l=r, mn<=add\)的节点,我们根据\(a[l]\)的值去更新此节点的\(mn\),我们为了知道\(a[l]\)的值,所以还需要维护每个区间位置最靠左元素的值。

code:

2018/10/12


Educational Codeforces Round 52 (Rated for Div. 2)

C

  • 对这些物品按高度进行基数排序。
  • 按高度从大到小进行扫描。

D

  • 一开始默认在中间点不换乘,于是被hack了。打得烂
  • 只知道xjb突突突,活该被hack啊!
  • 记录当前位置,下一个目的地,交通工具。状态数为\(100*100*3\)然后再枚举下一步该怎么走就好。

E

  • 这个操作,相当于把字符串首尾相接拼成一个圆环。设拼接点为mid, 那么操作\(b[i]\)就相当于交换mid左边长度为\(b[i]\)的串,和右边长度为\(b[i]\)的串。
  • 对于多种操作,我们可以发现区间\([b_{i-1},b_i)\)相互独立,我们把每个区间对答案的贡献相乘即可。

F

  • 这题又开始xjb突突突了。假做法:在每个树叶上放个硬币,然后把每个硬币向上移k步。求一条从根出发的链,使得路径上硬币最多。这就是典型的不动脑子!
  • 真做法:我们考虑DP。
  • \(f[u]\):表示硬币自闭在以\(u\)为根节点的子树内,最大答案。
  • \(g[u]\):表示硬币进入\(u\)为根节点子树,又走出\(u\)的子树,最大的答案。
  • 我们考虑\(u\)的儿子\(v_1,v_2,v_3.....\)怎么转移到\(u\)。要转移到\(u\)肯定在儿子里面选择一个自闭的,其它的不自闭。\(f[u]=max\{f[v_i]+\sum g[v] - g[v_i]\}\)
  • 接下来考虑\(g\)怎么推。\(g[leaf]=1\), 当\(u\)到其子树中深度最小树叶距离小于等于k时,\(g[u]=\sum g[v]\)

G 待补

2018/10/13


(NWERC 2017)题解

A 🐻干的,不关我的事

B \(max(n+2,1)\)

C

D 🐻干的,不关我的事

E

F 预处理每个数字,左边第一个与其不互质元素位置L[i],右边第一个与之不互质元素位置R[i],那么每个数字都对应一个区间,我们先要选择一个区间mid,使得\(L[mid],R[mid]\)能够覆盖\([1,n]\),接下来我们要在\([1,mid)\)中找个区间覆盖\([1,mid)\), \((mid,r]\)中找个区间覆盖\((mid,r]\),类似于快速排序的做法,从两边向中间搜索合法的\(mid\),code

G k边形,会把二维平面分成k个象限,每个象限单独考虑即可。

H 不妨设\(a<b<c\),然后考虑最小值。最小值可能在\([a,b)\),\([b,c)\),\([c,+)\)内,在每个区间内,目标函数与最小值满足开口朝上二次函数关系,故最大值一定在端点处取得。

I\(d-s\)的值,从大到小排序,然后01背包+输出解。

J 🐻干的,不关我的事

K 和17南宁区域赛那道题很相似,建一棵树,每个点记录子树中叶子节点表示的每个人苟住的概率。然后自下向上合并。\(T(n)=T(n/2)+O(\frac{n^2}{4})\)

2018/10/16

Codeforces Round #272 (Div. 1)


A\(x=pb+q\), 枚举\(q\)的值。

B 首先我们发现,只要考虑\(k=1\)的情况就好了。我们在第\(x\)组放\([6x+1,6x+2,6x+3,6x+5]\),根据辗转相除,这些数字两两互质。这样得到\(m\)也是最小的,因为每四个数中,最多有一个偶数,至少有3个奇数。

C 预处理好,\(s\)串中每个位置,作为匹配上\(t\)串的结尾,最靠后的开头位置在哪。考虑DP,\(dp[i][j]\)\(s\)串前\(i\)位,匹配上\(t\)\(j\)次,最少需要删几个字符。\(dp[i][j]=min(dp[i-1][j],dp[pre_i-1][j-1]+(i-pre_i+1-tlen))\)

2018/10/17###

Codeforces Round #265 (Div. 1)


A 串合法的条件是没有长度为2,3的回文串,即对于任意位置i,s[i]!=s[i+1],s[i]!=s[i+2]。枚举答案与原字符串的LCP。LCP之后,贪心取最小即可。

B 固定第一个点,然后\((3!)^7\)枚举每个点的顺序。然后求两两之间的距离即可。在\(C(8,2)=28\)个距离中,应有12个为\(d\), 12个为\(\sqrt 2d\),4个为\(\sqrt 3 d\)

C 考虑DP,用\(f[i][j]\)表示,字符\(j\)在第\(i\)$n$步操作后,模$M$的值。$g[i][j]$表示,$10^{len}%M$,$len$为字符$j$在第$i$\(n\)步操作后的长度。

2018/10/16

ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)


A 水题

B 个人感觉,对圆心和两两圆交点进行check就好【待补】

C 水题

D 枚举在左图选哪些人,对这些人在右图的后继,求交。

E 没看

F 水题

G 枚举最后停在哪个点,最终停在某个点的合法权值是一个区间。用树DP求出上界下界就好。

H 把每个商店,最小值,次小值拿出来,前k大之和便是答案。

I 二维LIS,用BIT维护就好

J 把相交的圆用并查集合并。每个并查集维护最左端的点,和最右端的点。

K 考虑区间dp,\(dp[i][j]\),区间\([i,j]\)有多少种合法的划分方案。

L 没看。

2018/10/21

Codeforces Round #517


2A 按题意模拟,统计每一圈的答案。

2B \(dp[i][j]\)\(i\)位,填\(j\),前\(i\)位能否合法。DP的时候,记录前驱,以输出解。

1A

自己的做法【可能是假的】:我们填入这两天的数字,一定是\([1,x]\)内所有的数字。不妨设\(a<b\),求出\(y(y+1)/2\geq a\)的最小\(y\),然后从\(y\)\(1\),逐个尝试放入第一天,那么第一天一定能放满。剩下的数字,从小到大,逐个尝试放入第2天。

题解做法:求出\(x(x+1)/2\leq a+b\)的最大\(x\),这个\(x\)是答案上界,这个上界一定能取到,因为,把一天放满,剩下的数字可以全放在另外一天。

1B

我们首先让前缀的a尽可能多,\(dp[i][j]\)表示使得\((1,1)->(i,j)\)存在全是a的路径,至少需要修改几个字符。我们考虑\(dp[i][j] \leq k\),且\(i+j\)最大的所有位置【这些位置前缀a是最长的】,以这些位置为起点,\((n,n)\)为终点,做BFS,使得路径字典序最小。

1C

迷之构造题。比赛的时候什么想法也没有,逃跑了。

首先操作数\(n/3\),级别的,意味着我们平均1步,需要保证3个位置变成0.

当串长大于等于7时,如果长度为3的后缀为000,001,010,100,101,110,111我们1步操作,就可以让最后3位变成0,但011就很令人痛苦了。

但令人惊喜的是,当串长大于等于11时,我们可以在两步操作,让长度为6的后缀变成0【打表枚举所有情况得出的结论】,然后我们把这个后缀剪掉,不管它了,接着处理下一个后缀,直到,长度不够11,到那时,状压暴力。

1D

我们首先要有信仰。和因子有关的大部分东西,一定不会太多!

  • 打表发现,1~1000000,每个数字,分解质因数后,把指数扔到一个vector里,排好序。这样的vector只有289种。妙啊。
  • 对vector里的某个元素+1,-1 or 推入一个1的,代价都是1。设\(dis(a,x)\)表示把\(a\)的因子个数变成\(x\)最少需要多少代价,我们枚举\(x\)\(dis(a,x)+dis(b,x)\)的最小值即为答案。
  • 一个vector,如果属于289种,我们,对它进行一步操作。可能就不在那289种vector里了。
  • 所以,我们需要创立一些,不属于289种vector的中间节点。穷举,元素之和小于25,单调递增的vector,把这些vector当成中间节点【不会超过20000个】
  • 以vector为节点,BFS!求出\(dis(a,x)\)

2018/10/22

Good Bye 2013


A 按题意一步步模拟。

B 从1到n,再从n到1,再从1到n........

C 对所有元素排序,总小到大,考虑每个数字该变成什么

D 枚举s[1],s[2]首尾字母,包含多少个AC子串。

E 逃跑

F 先读入所有数据,建好树,倍增预处理LCA。然后逐个加点,在加点的过程中,维护树的直径。

G 待补

2018/10/23


2018-2019 ACM-ICPC Brazil Subregional Programming Contest

A 设横坐标和纵坐标的变化为\(x\),\(y\),\(x=0\),设\(f(Len)\)表示\(x^2+y^2\leq Len,x \geq 1,y \geq 1\)\(gcd(x,y)=1\)的方案数。
那么\(2*[f(R^2)-f(L^2-1)]+m(n-1)+n(m-1)\)就是答案了。其中\(m(n-1)+n(m-1)\)表示\(x=1,y=0\),\(x=0,y=1\)这两种情况。考虑\(f\)该怎么计算。
\(f(L)=\sum_{x=1}^{n-1}\sum_{y=1}^{m-1} (n-x)*(m-y) * [gcd(x,y)=1,x^2+y^2\leq L]\)按gcd的值分类一下\(f(L) = \sum_{g=1}^{n-1} \mu(g) \sum_{x=1}^{(n-1)/g}\sum_{y=1}^{(m-1)/g} (n-gx)(m-gy)[x^2+y^2 \leq (L^2/g^2)]\)。我们枚举\(g\)的值,然后对于\((n-1)/g,(m-1)/g,L^2/g^2\)值相等的\(g\)一起处理掉。

B 只有一块石头,就是很明显的Wythoff博弈。我们可以用\(sg(x,y)\)表示一个石头在\((x,y)\)位置,对应的SG值。然后把每块石头的SG值异或起来,然后这个做法就假掉了。因为!获胜条件是把一块石头送到\((0,0)\)而不是把所有石头送到\((0,0)\)啊。如果石头的初始位置有\(x,y\)相等的,那很妙,先手必胜。否则。那个GG的孩子,面对的,一定是所有石头都在\((1,2)\)或者\((2,1)\)的局面。因为,这两位选手是聪明的!能不送,就不会送,如果当前位置非\((1,2)\),非\((2,1)\)我们一定不会移动到\(x=y或x=0或y=0\)的那些位置上,那么把\(sg(1,2),sg(2,1)\)的值设为0,以及每个子游戏结束的终点就好了。

C 分别按\(x1,y1\)从小到大,一条一条线段地添加,如果与之前的线段有\(x\)个交点,那么平面就会增加\(x+1\)个区域。求交点时,统计下逆序对。

D 签到题

E \(O(slen*tlen)\)暴力

F 至今没看懂题,很烦躁

G 二分答案,check最大流是否满流。

H 好难不会【其实题都没读】

I 答案不会超过\(2n\),否则imposible,迭代\(2n\)次就好了。

J 斯坦纳树,\(dp[i][mask]\):前\(i\)个点,\(mask\)集合内的capital连通且capital度数为1的最小耗费。转移分两种:

  • 固定i:\(dp[i][x|y]=min\{ dp[i][x]+dp[i][y] \}\)
  • 固定mask:
    • u在mask内:\(dp[u][mask]=dp[v][mask]+dis(v,u)\)【这一层用SPFA转移】
    • Else:\(dp[u][mask|1<<u]=dp[v][mask]+dis(v,u)\)

K 不会

L 把这4个点染成红色,对着这4个点两两求LCA,把LCA染成红色,对没个红色节点check,如果同时在\((u,v),(x,y)\)路径上,我们把它染成蓝色,对蓝色的点两两求距离,取max即为答案。

M 睡觉

2018/10/25


Codeforces Round #518 (Div. 1)

A \(dp[i][j][3]\)表示,考虑前\(i\)位,第\(i\)位为,\(j\),0/1/2表示,第\(i\)位和第\(i-1\)位的大小关系。用\(i-1\)\(i\),维护前缀和转移。

B 找到重心,然后开始BFS,需要满足两个条件,BFS恰好进行K层,每个点有大于等于3个后继,所有点都入队一次,就OK。

C 这个问题来自于魔法侧势力。十字架即可

E 邻接矩阵的秩,即为树/森林的最大匹配。这个DP我还是没搞懂啊!

2018/10/26


Educational Codeforces Round 53 (Rated for Div. 2)

A 找相邻的不同的两位即可

B \(p[i]\)记录每本书的位置,然后用\(top\)维护,栈内还剩下几个元素。

C 枚举左端点,二分右端点。

D 设当前有\(T\)个金币,走一圈会耗掉\(x\)个,那么接下来\(T/x\)圈每圈都会消耗掉\(x\)个金币,剩下的金币数为\(T\%x\)。我们\(O(n)\)地遍历一遍计算\(x\)因为\(T\%x > T/2\),所以复杂度为\(O(nlogT)\)

E 数位DP,我们从高位到低位考虑,\(dp[i][mask][2][2]\):记录,前缀满足【前\(i\)位放好了,用掉的数字集合为\(mask\),是否触顶,有没有出现前导0以外的数字】这些条件的数字,\(i\)位以后数字之和。\(cnt[i][mask][2][2]\):记录,前缀满足【前\(i\)位放好了,用掉的数字集合为\(mask\),是否触顶,有没有出现前导0以外的数字】的数字有多少个。

F 待补

G 我们施展Big-Small战法,如果两个vector大小的乘积小于等于\(n\),那么我们两两枚举,然后计算LCP,累和。否则,设\(LCP(i,j)\)表示后缀\(i\)与后缀\(j\)的公共前缀,注意到\(LCP(i,j)=Min_{x=rk[i]+1}^{rk[j]} height[i]\),使用单调栈维护位置\(i\)后面第一个\(height[j]<i\)\(j\),与前面的第一个\(height[j]\leq height[i]\)\(j\),计算\(height[i]\)对答案的贡献就好。

2018/10/27

Codeforces #253 div1


A 枚举提供哪些线索,如果能将所有卡片区分出来则合法,对线索个数取min即可

B 虚拟参赛时...猜的结论...将概率从大到小,一个一个地尝试着拿,然后我们发现成功的概率先递增,后递减。我们输出最大值即可。证明方法啊....数学归纳吧

开始口胡【这么证明显然不正确】:

  • 拿1个人时,一定拿概率最大的那位。
  • 如果拿了从大到小的前\(k\)个人后,再拿第\((k+1)\)个人,成功地概率还是递增的,那么拿前\(k+1\)个人,一定是拿\(k+1\)个人的最优解【成功概率增量最大】

具体怎么做呢?好难不会。

C 优先考虑!a[i]<=a[nex] && a[i]<=a[pre]为上!优先把这样的元素全部拿掉,因为拿这样的数字答案不会变小,那么剩下的序列,一定是先增后减的,我们把除了最大的两个的数字加入答案即可。

D我们考虑DP,\(dp[u]\): 算上\(u\)节点连向父亲的那条边,\(u\)到其子树叶子节点,最小的最大值。
\(mx[u][0]\): 不算上u节点连向父亲的那条边,u到其子树叶子节点,最小的最大值。
\(mx[u][1]\): 不算上u节点连向父亲的那条边,u到其子树叶子节点,最小的次大值。
\(dp[u]\)的值有更新时,我们拿\(dp[u]\)去更新\(u\)节点父亲\(p\)\(mx[p][0]\),\(mx[p][1]\).这样复杂度是\(O(NlogN)\)的,证明过程类似于树链剖分。

2018/10/28


Tinkoff Challenge - Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2)

C: 如果Alice最小的字符小于Bob最大的字符,那么它们两个都把自己最好的字符放在字符串尽可能靠前的位置,否则,放在尽可能靠后的位置,这样就能让对手把字符放得尽可能靠前了。

D: 每个点自己向自己连边,如果两个点邻居的集合相等,那么这两个\(x\)的值一定相等,我们对\(x\)相等的点缩点,最后剩下的图去掉重边后,必须由若干条链组成的,否则不合法,我们给点依次编号后,对图进行check

E: 首先,呆毛会告诉我们,答案一定在中间的位置,何也?因为如果答案不在中间的位置,那么局势一定对一方有利【一方!什么一方!】那么另一方,一定会对称着拿,让最后剩下的数字,回到中间的位置。于是,我们分类讨论一下,对于\(n\%2=0\),当\(n \neq 1\)时答案等于\(max(a[n/2],a[n/2+1])\),否则答案等于\(min(a[(n+1)/2],max(a[(n+1)/2-1],a[(n+1)/2+1]))\)我们令这个东西等于\(b[i]\),拿掉\(k\)个数字后,答案就会等于\(a,b\)序列中的某个区间最大值。这个区间不断像两边生长,所以我们可以\(O(n)\)地维护最大值。

F: 又被线段树砸死了!我们可以使用线段树。对于每个节点,我们用\(sum[0] - sum[9]\)维护,每个数位在这个区间内出现位置的10次幂的和。比如3在十位出现一次,在百位出现一次,那么3对答案的贡献等于\(10+100=110\),然后我们还需要10个懒惰标记,\(nxt[10]\)记录区间内所有的0~9分别会变成什么。\(nxt[10]\)相当于一个映射,这个映射是具有传递性的,pushdown的时候,我们要把父节点的映射\(nxt[10]\)同时叠加到到左儿子,和右儿子的\(nxt[10]\)映射上,同时更新左儿子,和右儿子的\(sum\)数组。

2018/10/29


Codeforces Round #519 by Botan Investments 【又是打得烂的一场啊】

C 把串分成很多段连续的a和连续的b,从前往后扫,遇到连续a和连续b的最后一个字母就进行翻转,翻转后字符串一定是a..ab..b,或b..ba..a这样的形式的。需要注意的是,如果当前在处理最后一位,且当前串为aaaabbb时不用翻转。

D 枚举公共子串在第一个位置的起点\(L\),然后右端点\(R\)一直往右边拱,拱到拱不动为止。那么\([L,R]\)的所有子区间都是可以作为公共子串的,对答案的贡献为\((R-L+1)(R-L)/2\)
然后把左端点\(L\)跳到\(R+1\),一段一段地处理。

E 我们先假设没有边,然后再把每条边的贡献减掉。\(x_1+y_2<x_2+y_1\)等价于\(x_1-y_1<x_2-y_2\),然后对\(x-y\)的值排序,然后维护前缀和,后缀和就好了。

F 妙啊,使用方案数来判定这种存在性问题,一种很妙的战法。我们用\(f(x)\)表示选出\(k\)个数字,使得这些数字gcd恰为\(x\)的方案数。这个很难施展,所以我们可以先求\(g(x)\):选出\(k\)个数字,使得这些数字gcd为\(x\)的倍数的方案数。那么\(g(x)=\sum_{x|n} f(n)\)然后莫比乌斯反演就能求出\(f\)了,我们只需判断\(f(1)\)是否大于0即可。

2018/10/30


Educational Codeforces Round 5【依然打得烂】

C 把相邻的.使用并查集合并。对每个*把它上下左右的并查集并起来,size就是答案了。

D 双指针,注意l,r更新的顺序。

E 跳跳狗基本操作 \(n\%k=n-(n/k)k\),对\(k\)的值进行分块。当\(n,m\geq1e13\)时。
n%MOD*m%MOD很GG啊。应该是(n%MOD)*(m%MOD)%MOD

F 哇!这个题我拿着rank当SA用是什么智熄操作啊!把所有字符串用不同的分隔符隔开拼接,然后buildSA+buildHeight+buildStack连招.最终的答案一定是一个后缀,或者是多个后缀的LCP。

  • 如果是一个后缀,那么,排名在它后面的人不能包含它,我们用这些后缀逐个去更新答案。
  • 如果是一堆后缀的LCP,这些后缀的rank一定是连在一起的,设他们的排名为\(l\)~\(r\)那么\(min_{i=l+1}^{r} height[i]\)就是它们LCP的长度,我们统计每个\(height[i]\)作为区间最小值对答案的贡献,这个我们用单调栈,维护每个位置,上一个比它小的height和下一个比它小的height,然后前缀和差分就好。

2018/10/31

Manthan, Codefest 16


魔禁怎么还不更新啊!

A 枚举\(ax+by=c\)\(x\)

B \(x\)的阶乘末尾0的个数等于\(x/5+x/25+x/125+....\),枚举\(x\)即可。

C\(f[i]\)表示,匹配串前\(i\)项,能否被\(m\)个串拼接出来。

D 枚举首项,第二项,逐项递推。考虑到Fib数列递增是指数级的,算上map,复杂度\(O(n^2log^2n)\)

E 枚举左端点,然后我们会发现,随着右端点右移动,\(100max(l,r)\)单增,\(min(l,r)\)单减,我们二分\(100max(l,r) \leq min(l,r)\)的最大\(r\),然后在这个最大\(r\)两侧check更新答案即可。确定好每个\(l\)对应的答案后,就是个很经典的从\(n\)个元素中拿出\(k\)个元素,最小值期望问题了。

F 考虑树形DP。设两条路径为\((a,b)\),\((x,y)\),那么\(Lca(a,b),Lca(x,y)\)的两棵子树,一定是包含,或相离的关系。我们用\(dp[u]\)表示\(u\)节点子树内最长路。\(down[u]\)表示从\(u\)节点向子树内走,最长路径. \(up[u]\)表示,从\(u\)节点,向\(u\)的子树外面走,最长路径。儿子更新父亲+父亲更新儿子,两次DFS,这三个东西就能预处理好。

  • 相离:枚举\(u\),拿\(dp[son_1]+dp[son_2]\)更新答案。
  • 包含:枚举\(u\),使得\((a,b)\)穿过\(u\)\((x,y)\)\(u\)的某个儿子的子树内。按照如下两种情况更新答案
    • \(down[son_1]+a[u]+up[u] + dp[son_2]\)
    • \(donw[son_1]+down[son_2]+a[u] + dp[son_2]\)

G 按DFS序建线段树,每个线段树节点,用一个bitset维护,区间内的元素膜\(m\)有哪些可能。

H 离线询问后,莫队,对\(a[]\)序列离散化后,建权值线段树。若插入元素\(x\),那么比\(x\)大的所有元素,乘上的fib值,右移一位。若删除元素\(x\),那么比\(x\)大的所有元素,乘上的fib值,右移一位。左移右移可以通过乘上一个二阶矩阵来实现。权值线段树的懒惰标记,维护这个二阶矩阵就好。

2018/11/02


Codeforces Round #238 (Div. 1)

魔禁3的暗部大战为什么如此辣鸡啊?!

A\(i\neq j\)\(a_{ij}a_{ji}\)会对答案产生两次贡献,不影响奇偶性。
因此答案是0还是1,取决于对角线上1的个数的奇偶性。

B 这个等式给人一种,要凑平均值的感觉。如果\(i\)出现了,\(1000001-i\)没有出现,那我们直接拿\(1000001-i\)。如果\(i,1000001-i\)都出现了。我们就选择一对都没出现过的\((j,1000001-j)\)

D 先求出每个点的下一步跳哪,然后就变成一个树上求LCA的问题了。考虑后继该怎么求。点\(i\)下一步跳到\(j\),那么第\(i\)个点连向第\(j\)个点,连线的斜率,一定去到极值。这个我们从后往前扫,维护一个凸壳就好。

2018/11/03


ACM International Collegiate Programming Contest, Arabella Collegiate Programming Contest (2018)

B 如果子树不是一条链,答案一定是-1。考虑一条链最少修改次数,设链上的权值分别为\(a_1,a_2,....a_k\)现在我们需要把它变成公差为\(1\)的等差数列。统计\(x=a_i+i\)的值,并记录出现次数最多的\(x\)\(k-cnt_x\)即为答案。如果\(u\)节点的子树是链,有两种情况。1.u是链的端点 2.u不是链的端点。情况1自下向上更新就好,情况2则枚举所有的\(u\)节点。复杂度\(O(n)\)

I 为了让\(m\)个人出现时,所有钥匙都有。每个钥匙,至少要被分给\(n-m+1\)个人。即至多\(m-1\)个人没有钥匙,所以我们有\((n-m+1)x=ny\)。为了让\(m-1\)个人出现时锁无法打开,我们需要\(C(n,m-1)\)种钥匙,因为从\(n\)个人中选出\(m-1\)个人,有\(C(n,m-1)\)种选择方法。而我们需要让每种方案都至少缺失一种钥匙。

Codeforces Round #289 (Div. 2, ACM ICPC Rules)

B 考虑-1的判定,如果极差大于k,那么就不合法,否则,我们通过每种颜色,都使得极差逐次减少1。

C 第一个串很好确定,然后我们枚举第\(i\)个串和第\(i-1\)个串的LCP。\(i>=2\)

D 对于不同的\(j\)\(w[i][j]-w[i+1][j]\)在模\(k\)系下,值必须相同。我们可以根据这个求出\(a,b\)的差分序列。

E 枚举区间的长度\(len\)。我们用\(sum_i\)表示1~i元音的个数。长度为\(len\)的所有区间出现的元音数总和为\(\sum sum_{i+len}-sum_{i}\)。这个可以通过对\(sum\)求前缀和,来统计。

F\(dp[i][j]\)表示,\(a_i\)~\(a_j\)能表示多少种以\(a_i\)为根的树。关于\(dp[i][j]\)的转移,我们可以枚举\(a_i\)第一棵子树对应的区间,设这个区间为\([i+1,x]\),那么\(a_{x+1}\)一定大于\(a_{i+1}\)。我们用\(dp[i][x]*dp[x][j]\)去更新\(dp[i][j]\)就OK了

2018/11/05


Lyft Level 5 Challenge 2018 - Final Round (Open Div. 1)

A 双指针,第一个指针枚举保留几根竖的,第二个指针枚举保留几个横着的。

B 我们不妨以\(a_1\)为根。在自己的树上,拆掉自己的点,树一定会变成一片森林。如果交集为空,那么排骨龙选择的点,一定全在森林的某棵树内。如果排骨龙选择的某个点,出现在了森林的某棵树内,我们只需看看这棵树根节点的父亲,有没有在排骨龙选择的点内就OK了。

C \(n \geq 4\)时,答案一定是\(max_x+max_y-min_x-min_y\)。这是因为当点\(p\)的横坐标\(p_x\)不为极大极小值时。\(p_x\)对答案的贡献,一定是一次正的一次负的,所以它对答案的贡献为0。考虑\(n=3\)的情况。根据抽屉原理,3个点,一定有个点同时占据这3个点中的\(max_x,max_y,min_x,min_y\)中的两个。我们枚举这个点。

D 施展并查集,我们维护每个并查集的大小\(sz[x]\),与每个点和根节点的异或值\(dis[x]\)。如果知道了\([l,r]\)的异或值等于\(x\),那我们把\(l-1\)\(r\)所在的并查集进行启发式合并。对于查询,如果两个点不在同一个并查集内,答案为-1。否则答案为\(dis[u]\) ^ \(dis[v]\)

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)

C 分为3种情况,CC,CD,DD。CD很好解决,对于CC和DD,我们按照价格从小到大进行排序。枚举价格更高的那个,那么价格更低喷泉,价格一定在\([1,x]\)这样的区间内,用BIT维护前缀最大值就好。

D 分两次算。第一次w->a,h->b,第二次w->b,h->a。考虑贪心策略,我们使用的数字,一定是最大的\(k\)个,枚举这个\(k\),我们会发现\(k\)不会超过34,我们可以对这\(k\)个数字进行折半枚举,把\(k\)个数字分成两堆,先枚举第一堆的子集,让这个集合去乘w。然后在第二堆里lower_bound一个使得w能满足要求的集合。剩下的所有数字,去乘h就好了。如果w,h都能满足要求,那么\(k\)步操作,就能满足要求了。

E 我们先对物品进行分类。A喜欢B喜欢,A喜欢B不喜欢,A不喜欢B喜欢,AB都不喜欢。然后从小到大枚举AB都喜欢的物品个数\(x\),那么A喜欢B不喜欢,A不喜欢B喜欢的,我们至少要拿最小的\(k-x\)个。如果还没拿够\(m\)个的话,从剩下的物品里,从小到大拿。我们可以用权值线段树维护剩下的物品的前\(x\)大值。

2018/11/06

睡了一天觉

2018/11/07

Good Bye 2014


B 如果\(i,j\)能交换,那么用并查集合并\(i,j\),对每个并查集内元素排序。

C 这个问题长得很贪心。我们拿出一本书时,应让它上面的书轻一点。考虑\(b_i\)序列中第\(i\)本书对答案的贡献。我们找到它上一次被置顶的时间\(j\),然后发现\((j,i)\)区间内的书的集合,必须要搬。这便是答案的下界,这个下界是可以取到的。

D 考虑每条边对期望的贡献。一条边会把树分成两部分。如果3个点全在一侧,那么这条边对答案的贡献为0,否则对答案的贡献为两倍边权。

E 求出推倒第\(i\)个骨牌,在\(i\)之后第一块不倒的骨牌:\(nex[i]\)。这个可以从\(n\)\(1\)倒着推,用线段树维护\(nex[i]\)的区间最大值或者单调栈都能苟。因为是要我们求最少要增长多少,我们用\(cost[i]\)推倒\(i\)使得\(nex[i]\)也能倒下的最小代价,这里我们一定是给\([i,nex[i])\)\(p+l\)最大那个骨牌增长。对着\(nex,cost\)施展倍增就稳了。

F 每个查询,相当于对\([a_i,a_i+P)\)的区间做背包。我们可以对时间进行分治。考虑时间区间\([l,r]\)里的询问,\(mid=\frac{l+r}{2}\),查询分为3种:\([a_i,a_i+P)\)\(mid\)左侧,右侧,或跨过\(mid\)。在左侧右侧我们可以分治,跨过\(mid\),我们可以对\(mid\)左侧,从右到左施展背包【后缀】。\(mid\)右侧,从左到右施展背包【前缀】。一个查询的区间\([a_i,a_i+P)\)可以由一个后缀和一个前缀拼接而成。分治会进行\(logT\)层,每层预处理背包的复杂度为\(O(nV)\),因此预处理背包的复杂度为\(O(nVlogT)\),出来每个询问时,我们枚举\(mid\)左侧拿的体积,因此每组询问是线性的。总复杂度\(O(nVlogT+qV)\)

2018/11/08

2018-2019 Всероссийская командная олимпиада школьников по программированию, интернет-тур + отборы регионов (ВКОШП 18, интернет-тур)

A 15 🐶

E 7 🐱

G 54(-3) 🐱 对\(n\)的奇偶性进行讨论。如果是偶数+-+-+-这样构造。如果是奇数,前3项3*4*5 = 2*3*6之后按照+-+-+-的顺序构造就好。

H 63(-2) 🐶 枚举前两项。

L 71(-4) 🐶 苟狗食鲨鼻

I 81 🐻

D 108 🐱 类似于BFS的做法。先让度数最大的点进队列,然后把度数最大的点,和度数前\(deg\)大的点依次连边,更新度数,并让这些点进队。

C 130 🐱 把物品按T从小到大排序,从后往前做一次背包,枚举答案集合的mex就了。

K 201 🐻

J 261 🐶 在每个2*2的格子中画一个顺时针的环,我们可以用环形的链表来维护这个环,然后我们对连通块进行DFS,在DFS的过程中,对环进行合并,合并的时候,施展链表插入就好。

B 考虑让某个人不适,的条件集合。这个集合里,只要有一个为真,其它都一定为假。这是个很明显的2SAT问题,但是建图边是\(N^2\)级别的。我们可以建出36个虚拟节点。

  • 第1个代表命题:【集合中编号第1位为0的条件,全是假的】,第2个命题【集合中编号第1位为1的条件,全是假的】
  • 第3个代表命题:【集合中编号第2位为0的条件,全是假的】,第4个命题【集合中编号第2位为1的条件,全是假的】
  • 第5个代表命题:【集合中编号第3位为0的条件,全是假的】,第6个命题【集合中编号第3位为1的条件,全是假的】

建出这些虚拟节点后,按照逻辑条件连边后,跑2SAT。

2018/11/09

2017 ACM-ICPC Asia Amritapuri Regional Contest

暗部大战剧情好赶啊,有种全程两倍速的感觉。

B\(f(x)-g(x)\)\([L,R]\)内积分。

D 答案一定不会超过6位。我们记录每个数字对应的合法结尾位置,然后用小的数字推大的数字。

F 树链剖分【雾】。用链表维护上一个非1的数字。因为几何级增长的爆炸性,\(x\)经过log层后就会变成1

H 二分答案,判断\(x\)时保留权值小于等于\(x\)的边,进行SCC缩点,合法当且仅当,图是一条链+一些前向边。做拓扑排序是判断队列大小是否一直小于等于1即可。

I 预处理每个前缀,每个后缀是否具有严格单调性。枚举删除哪个元素。

J 签到题

K 逐位考虑,从小到大一个个尝试,对字母和位置建图,用网络流满流判断合法性。

E 【待补】用二元组\((u,v)\)表示这个人,刚刚从\(u\)走到\(v\),那么我们会得到一个\(2m\)个节点的有向图。有向图博弈。

2018-2019 CTU Open Contest


A 签到题

B 如果两个点的坐标差为\((dx,dy)\),那么距离为\(max(|dx|,|dy|)\)。对于查询的一个点,我们可以以之为中心把平面分成八块。对于每一块求一下前缀最值。如果坐标\(1e18\)怎么做啊?对于\((x_0,y_0)\),考虑\([135.5°,180°]\)区域我们需要查询\((x,y)\),满足\(y<y_0,x_0-y_0<x-y\)的所有点中\(x\)的最大值。CDQ分治一下,BIT维护前缀最大值,感觉可做

C 按题意模拟

D 把所有串插入AC自动机,如果节点\(x_0\)的后继为\(x_l,x_r\),那么\(E(x_0)=0.5E(x_l)+0.5E(x_r)+1\),建立线性方程组,高斯消元即可。

E 用后缀数组,求出长度为\(k\)的字符串,字典序的排名。最小化最大值问题,可以二分答案。我们二分最高的排名\(x\),看看排名小于等于\(x\)的串,能不能覆盖满整个环。对于跨过\(1\)的串,我们可以拆成两半。然后就变成若干个区间能不能覆盖\([1,n]\)的经典问题了。

F 数位DP,方案数可用\(f(a+2^n-1)-f(a)\)这样作差。\(dp[i][j][2]\)表示前\(i\)位放\(j\)个1,是否触顶的方案数。

G 对棋盘进行黑白染色。因为从白格一定会跳到黑格。所以如果先手与后手初始位置异色,那么一定是先手抓到后手。反之,如果同色,一定是后手抓到先手。

H SG函数。记忆化搜索。

I 把点按先\(x\)\(y\)的顺序插入set,枚举当前最小的点,从小到大逐个尝试着给它匹配下一个点,下一个点和当前的最小的点构成的正方形,面积越小越好。可以进行这个预测性剪枝,如果\(dx^2>S\)那么,不可能构成面积更小的正方形,此时退出匹配。

J 按位统计对答案的贡献。枚举了\(bit\)位后,那么根据\(v_i\)\(bit\)上的数值,每个节点的权值可设为0或者1,那么这一位对答案的贡献为\(2^{bit}*\)所有点均为1的路径数。

posted @ 2018-03-29 01:00  RUSH_D_CAT  阅读(383)  评论(0编辑  收藏  举报