2135C By the Assignment
如果图是树,那么 \(-1\) 的点可以随便赋值。考虑有环的情况。通过推性质,找环上相邻两点的两条路径,可以推出:奇环上都是 \(0\),偶环上点权都相等。进而推出每个边双的点权都相等。边双缩点,判一下无解,直接算即可。
2120D Matrix game
鸽巢原理,首先考虑 \(b=1\) 的情况,此时只需要一列中有一种颜色出现 \(a\) 次,因此当 \(n\ge k(a-1)+1\) 时一定可以。扩展到 \(b>1\) 的情况,此时需要有 \(b\) 列中出现 \(a\) 次的那种颜色相同,并且位置相同,因此当 \(m\ge k\binom na(b-1)+1\) 时一定可以。
要找的 \(b\) 列不一定需要一模一样。
2112E Tree Colorings
首先蓝点的子树里一定只有蓝点,黄点的子树里一定只有黄点。假设已经有了一棵树,令 \(g_i\) 表示 \(i\) 为绿点时 \(i\) 子树内方案数,有 \(g_i\larr g_i(g_v+2)\),发现转移是做乘法,因此令 \(f_i\) 表示有 \(i\) 种方案的最少点数,有 \(f_i=\min_{d|i,d<i}f_{\frac id}f_{d-2}\)。转移点只有奇数,因此偶数无解。
这种反过来的 DP 写出来正着的 DP 转移式会更好做。
2097B Baggage Claim
容易转化为:有 \(k\) 对数,每对数选一个,\(k\) 个数互不相同的方案数。建图,每对数之间连边,选一个数转化为让边指向它,需要让每个连通分量都是叶向基环树或树,每个基环树有 \(2\) 种方案,每棵树有 \(size\) 种方案,乘起来即可。需要去掉自环,且需要判无解。
转化成给边定向是一种常见的 trick。
2096D Wonderful Lightbulbs
容易转化为 \(2\times2\) 矩形翻转。发现由于保证有解,两个横坐标或纵坐标相同的一定可以被消掉,只需要找到落单的横纵坐标就可以了。
另解:发现每次操作前后所有坐标异或和不变,直接异或就可以了。
2092E She knows...
条件可转化成所有相邻格子颜色异或的异或和为 \(0\),考虑每个点的贡献,发现只有在边上且不在角上的点有贡献。考虑这些点,如果其中有绿点,那么绿点除了它都能任取;否则把这些点异或一下,非 \(0\) 则无解,否则绿点都能任取。
没转化硬推也能做,但是我不会。
2077C Binary Subsequence Value Sum
好题,多写点。
原教旨主义推式子题。
\(F(v,l,r)\) 即区间内 \(1\) 的个数减 \(0\) 的个数,所以 \(F(v,1,i)+F(v,i+1,len)=F(v,1,len)\),由均值不等式可知,当前面两项比较接近时取到最大值。令 \(\Delta=F(v,1,len)\),对奇偶性分讨可知区间分数为 \(\lfloor\frac\Delta2\rfloor\lceil\frac\Delta2\rceil=\frac14(\Delta^2-\Delta\bmod2)\),发现 \(\Delta\) 与 \(len\) 奇偶性相同,因此分数为 \(\frac14(\sum\Delta^2-2^{n-1})\)。
展开 \(\sum\Delta^2\) 得:
有结论:
可通过拆组合数推式子证明。代入上式即可得答案。
2072G I've Been Flipping Numbers for 300 Years and Calculated the Sum
分讨一下,当 \(p>n\) 时 \(rev=n\),可以直接求和;当 \(\sqrt n<p\le n\) 时 \(rev=p(n-\lfloor\frac np\rfloor p)+\lfloor\frac np\rfloor\),可以数论分块;\(p\le\sqrt n\) 可以直接算。复杂度 \(O(T\sqrt n)\)。可以证明复杂度是不带 \(\log\) 的,但是我不会。
2066C Bitwise Slides
Key Observation:\(P\oplus Q\oplus R=pre_i\),由于一定有一对数相等,剩下的那个数一定是 \(pre_i\)。
因此,令 \(f_{i,j}\) 表示第 \(i\) 次操作后相等的数为 \(j\) 的方案数。转移需要分讨一下:
- 当 \(j=pre_{i-1}\) 时,三个数为 \(pre_{i-1},pre_{i-1},pre_{i-1}\),三个都可以转移;
- 当 \(j=pre_i\) 时,三个数为 \(pre_i,pre_i,pre_{i-1}\),三个都可以转移;
- 否则,只能让 \(pre_{i-1}\) 变为 \(pre_i\)。
实现上,由于 \(j\) 可能很大,但有效的 \(j\) 只有 \(O(n)\) 个,考虑用 map 存储;暴力转移是 \(O(n^2)\) 的,考虑滚动数组,需要访问的位置只有 \(j=pre_{i-1}\) 和 \(j=pre_i\),复杂度是可以接受的。
需要前面的 Key Observation,并且需要注意到状态数比较少。
2065H Bro Thinks He's Him
令 \(f_{i,0/1},g_{i,0/1}\) 分别表示以 \(0/1\) 结尾的子序列的答案和个数,容易得出转移方程。线段树维护 \(5\times5\) 矩阵即可。复杂度 \(O(k^3n\log n)\),卡一卡能过。
数数解法:发现 \(f(t)=1+\sum_{i=1}^{len}[s_i\neq s_{i+1}]\),考虑计算每对不相等的数的贡献。钦定 \(i,j\) 为一对相邻的数,答案为:
每个数对前后都有贡献,拆式子分别用树状数组维护一下就好了。我没写。
2148F Gravity Falls
每次在所有非空串里找字典序最小的,把新的部分加入答案,然后把所有字符串长度不超过它的部分都砍掉。每个元素只会被访问 \(O(1)\) 次,由于总长度有保证,复杂度是对的。
2145E Predicting Popularity
令 \(v_i=\max(a_i-ac,0)+\max(d_i-dr,0)\)。一个人 \(x\) 被选有两个条件:\(v_i<v_x\) 的 \(i\) 都被选了,并且 \(v_i<v_x\) 的人数 \(\ge v_x\)。先不考虑前面的条件,令 \(cnt_i\) 表示 \(v_j<i\) 的人数,第二个条件可转化为 \(cnt_{v_x}-v_x\ge0\)。可以用线段树维护它,每个数对后缀有贡献,可以做区间加。第一个条件即前缀最小值 \(\ge0\),可以直接线段树上二分。二分出来的是 \(v_x\),需要另外用树状数组维护人数。
遇到多种限制时,可以考虑分开处理,转化贡献。
2155E Mimo & Yuyu
发现答案与 token 奇偶性有关,按照 \(n\) 是否等于 \(1\) 分讨一下。
当 \(n>1\) 时,如果每一列都有偶数个 token,那么每次 Mimo 操作完 Yuyu 可以直接做跟他本质相同的操作,最后 Mimo 就输了;否则,Mimo 可以直接操作最右边的奇数列单出来的那个 token,让前面所有列都有偶数个 token,之后先手变成 Yuyu,Mimo 就赢了。因此,先手必胜当且仅当存在一列有奇数个 token。
考虑 \(n=1\) 的情况。手玩发现第 \(i\) 列的 token 对答案有 \(2^{i-2}\) 的贡献,因此只有第 \(2\) 列的 token 会影响答案的奇偶性。判一下即可。
2147E Maximum OR Popcount
考虑算出每个答案所需的最小操作次数。枚举操作的最高位 \(w\),从 \(w\) 到 \(1\) 位进行操作。每次遇到空位,选低 \(w\) 位最大的元素,把它的低 \(w\) 位变成 \(2^w\)。可以证明这样是最优的,否则如果选的元素更小,那么操作它时一定会在某一步变成最大值。
2146E Yet Another MEX Problem
令 \(R\) 表示当前右端点,所求即 \(\max_L\sum_{i=L}^R[a_i>\mathrm{mex}_ja_j]\)。由于 \(\mathrm{mex}\) 本身是最小的,考虑转化为:
令 \(\mathrm{last}(x)\) 表示 \(x\) 上一次出现的位置:
显然当 \(R\) 一定时 \(L\) 越小 \(\sum_{i=L}^R[a_i>x]\) 越大。于是所求即:
在值域上开一棵线段树,插入 \(a_i\) 时将 \(a_i\) 的位置置为 \(0\),\(<a_i\) 的位置区间 \(+1\),维护最大值即可。
要善于利用 \(\mathrm{mex}\) 的性质。
2146D2 Max Sum OR (Hard Version)
如果有两个数 \(a_i,a_j\) 满足 \(a_i\&a_j=0\wedge a_i|a_j=2^k-1\),那么这两个数互相匹配一定是最优的。之后会剩下一些数,把它们按最高位分成两部分,去掉最高位后每一部分又回到了之前的情况,可以递归处理。最后剩一个就自己或自己。
2140D A Cruel Segment's Thesis
考虑 \(n\) 为偶数的情况。把所有线段划分成 \(L,R\) 两个大小为 \(\frac n2\) 的集合,表示作为左端点或右端点。答案即:
按 \(l_i+r_i\) 排序即可。
考虑 \(n\) 为奇数的情况。此时 \(|L|=|R|=\frac{n-1}2\),考虑枚举多出来的元素 \(x\)。有两种情况:
- \(l_x+r_x\) 在后一半,此时按上式计算,减去 \(x\) 的右端点即可;
- \(l_x+r_x\) 在前一半,此时需要把第 \(\frac{n+1}2\) 加入 \(L\) 中,按上式计算,再减去 \(x\) 的右端点。
贪心可以考虑写式子。
2134D Sliding Tree
找直径上度数 \(>2\) 的点,令它为 \(b\),\(a\) 为直径上的点,\(c\) 为不在直径上的点。
证明:把树变成链,可以转化为让直径 \(=n\)。每次进行如上操作都能使直径增加 \(1\),因此是最优的。
2127E Ancient Tree
把一个点染成子树里没有的颜色一定是不优的。如果一个点子树内有 \(\ge2\) 种颜色在 \(\ge2\) 个儿子里出现过,那么这个点一定是 cutie 的,可以随便染;否则,如果只有一种颜色在 \(\ge2\) 个儿子里出现过,那么染成这种颜色;否则随便染。但是需要考虑子树全 \(0\) 的情况,此时染成父亲的颜色即可。由于只需要判断颜色出现在 \(2\) 个儿子里,可以使用启发式合并 + set 维护。
有虚树做法,但它是一道 \(2100\)。
2124E Make it Zero
不难发现答案 \(\le2\),没发现也能做。
当 \(\sum a_i\bmod2=1\) 或最大值 \(>\frac{\sum a_i}2\) 时无解。如果能找到前后缀和相等的分界点,答案为 \(1\);否则找到两边差最小的位置,做一次操作把小的那边推平,之后用一次操作把剩下的部分推平。令两边的差最小为 \(\Delta\),则第二次操作 \(b_i\le\frac\Delta2\)。
证明:不妨设在位置 \(i\) 时两边差最小,且前缀和 \(pre\) 大于后缀和 \(suf\)。此时 \(pre-a_i<suf+a_i\),即 \(pre-suf<2a_i\)。因此 \(\frac\Delta2=\frac{pre-suf}2<a_i\);要证左边的其他数能凑出 \(\frac\Delta2\),即证 \(pre-a_i\ge\frac\Delta2\),只需证 \(pre+suf\ge2a_i\),由有解条件可知一定成立。所以需要倒着扫。
2123G Modular Sorting
发现每次 \(+k\) 操作不改变 \(a_i\bmod\gcd(k,m)\) 的值,因此考虑对每个 \(d|m\) 处理答案。每 \(d\) 个一块,把 \([0,m)\) 分成 \(\frac md\) 块,考虑最小化块的个数,如果 \(a_{i+1}\bmod d\ge a_i\bmod d\) 则把它们放进同一块,否则需要加一块。由于 \(d\le200\),可以直接做。
2150C Limited Edition Shop
考虑转化限制。令 \(p(i)\) 表示 \(i\) 在 \(b\) 中的位置,当 \(i<j\wedge p(a_i)>p(a_j)\) 时,选 \(a_j\) 就一定要选 \(a_i\)。转化成平面上的点 \((i,p(a_i))\),选一个点时左上方矩形里的点都要选。
考虑 DP。令 \(f_{i,j}\) 表示前 \(i\) 个元素里所有 \(p(a_k)\ge j\) 的点都被选的答案。有转移:
线段树优化即可。
2143D2 Inversion Graph Coloring (Hard Version)
因为只有两种颜色,所以好序列不能有长度 \(=3\) 的下降子序列,因此能划分成两条上升子序列。令 \(f_{i,j,k}\) 表示从 \([1,i]\) 中选元素,两条子序列的最后一项分别为 \(j,k(j\ge k)\)。转移显然。
考虑优化。滚动数组后发现只有 \(f_{a_i,k}\) 和 \(f_{j,a_i}\) 会被修改,修改的状态数是 \(O(n)\) 的,树状数组维护每行列的前缀和即可。
2138C2 Maple and Tree Beauty (Hard Version)
令叶子的深度最小为 \(mn\),去掉所有 \(dep>mn\) 的点,发现每一层染同一种颜色一定是最优的。如果能做到每一层染同一种颜色,那么答案为 \(mn\),否则答案为 \(mn-1\),可通过调整法证明。令 \(f_i\) 表示能否恰好凑出 \(k\) 个 \(0\),跑 \(01\) 可行背包即可。使用 bitset 优化,时间复杂度 \(O(\frac{n^2}w)\)。
2137G Cry Me a River
考虑给定红点的情况,此时可以直接按拓扑序 DP,令 \(f_{i,0/1}\) 表示当前在 \(i\) 节点,Cry/River 操作,Cry 是否必胜。转移显然。对于修改,考虑以 \(x\) 为起点进行 BFS,一直走到红点或没被修改的点。由于红点只会加不会删,当 \(f_{i,0/1}\) 从 \(1\) 变成 \(0\) 之后就不会再改变了,所以每个节点 \((i,0/1)\) 只会入队一次。
这里的 BFS 需要使用有向图博弈的特殊 BFS,即类似拓扑排序 + BFS 的东西。
2134E Power Boxes
由于修改次数不超过 \(\lceil\frac{3n}2\rceil\),考虑用不超过 \(3\) 次操作确定相邻的 \(2\) 个数。
令 \(f_i\) 表示 \(i\) 的弹跳次数,不难发现 \(f_i>f_{i+2}\),因此最多只有 \(\lfloor\frac n2\rfloor\) 对 \((i,i+1)\) 满足 \(f_i=f_{i+1}\)。考虑倒序枚举,并按这一性质分讨。
- \(f_{i+1}=f_{i+2}\wedge i>1\),此时可以通过 \(\mathrm{throw}(i-1)\) 确定 \(a_{i-1}\),\(\mathrm{swap}(i-1),\mathrm{throw}(i-1)\) 确定 \(a_i\)。
- \(f_{i+1}=f_{i+2}\wedge i=1\),此时有 \(f_{i+2}>f_{i+3}\),可以通过 \(\mathrm{swap}(i),\mathrm{throw}(i-1)\) 确定 \(a_i\)。
- \(f_{i+1}\neq f_{i+2}\),直接 \(\mathrm{throw}(i)\) 即可确定 \(a_i\)。
\(a_n\) 需要处理一下。
2131G Wafu!
排序,令 \(f_i\) 表示前 \(i\) 个元素删干净的次数,\(g_i\) 表示 \([1,i]\) 被删干净的次数,有:
不难发现 \(g_i=2^i-1\),因此有用的数在 \(O(\log V)\) 级别,乘积的递推式与上式类似,直接做即可。
2121H Ice Baby
从普通的 \(LIS\) 考虑比较困难,那么反过来,令 \(f_{i,j}\) 表示前 \(i\) 个区间,\(LIS=j\) 时,最后一个元素最小是多少。有:
考虑把 \(i\) 滚动掉,转移即前面 \(f_j\le l_i\) 的部分不变,向后平移 \(f\) 中值在 \([l_i+1,r_i]\) 内的元素,并在这一段左边加入一个 \(l_i\),对于右端点被覆盖的元素,发现 \(f\) 单调不降,因此可以直接删掉。使用 multiset 维护即可。
2120E Lanes of Cars
把 \(a_i\) 排序后,发现需要变道当且仅当 \(\max a_i-\min a_i>k\)。考虑二分最后的 \(\max a_i\),找到第一个满足 \(a_i>mid\) 的数能填满 \(a_i<mid-k\) 的 \(mid\),求出 \(\max a_i=mid\) 时,把 \(a_i<mid-k\) 的部分填满后剩下多少,把这部分分给每个满足 \(a_i<mid-k\) 和 \(a_i\ge mid\) 的 \(a_i\)。
2115B Gellyfish and Camellia Japonica
直接做比较困难,考虑构造序列 \(d\) 使得 \(\forall i\le n,a_i\ge d_i\),最终得到 \(c_i\ge b_i\)。
对于操作 \((x,y,z)\),有 \(c_z=\min(c_x,c_y)\Rarr d_z\le\min(d_x,d_y)\),倒序枚举操作,就有 \(d_x=\max(d_x,d_z),d_y=\max(d_y,d_z)\)。做完这次操作后,之前的操作对 \(d_z\) 不再产生限制,因此令 \(d_z=0\)。
由于 \(c\) 中的值不会增加,而上面的构造不弱于题中限制,让 \(a_i\) 取到下界 \(d_i\) 即可保证 \(c_i=b_i\)。无解的情况正着跑一遍判一下即可。
2114G Build an Array
考虑找到合法 \(k\) 的上界。如果一个数 \(x\) 是被拼起来得到的,令 \(x=2^tx'(x'\bmod2=1)\),则只有 \(2^ix'(i<t)\) 能拼成它。因此,当只有一个数时,上界为 \(2^t\),即加入 \(2^t\) 个 \(x'\),让它们拼成 \(x\)。
考虑有多个数的情况,由于只能往左边或右边加数,当一个数 \(x\) 被加入序列时,有两种情况:
- 它是第一个数,此时对答案贡献为 \(2^t\)。
- 它左边或右边的数 \(y\) 先被加进来。此时需要防止拼成 \(x\) 的过程中跟 \(y\) 合并。这种情况只会在 \(y=2^ix'(i<t)\) 时出现,此时只需要先加入一个 \(2^{i+1}x'\) 即可。
预处理出第二种情况的前后缀和,枚举第一个数即可。
实现上,可以暴力求 \(t\),复杂度 \(O(n\log n)\);也可以根据 \(2^t=\mathrm{lowbit}(x)\) 做到 \(O(n)\)。
2114F Small Operations
显然最优的方案是把 \(x\) 变成 \(\gcd(x,y)\) 再变成 \(y\),于是把 \(x,y\) 同时除以 \(\gcd(x,y)\),有 \(x\perp y\)。
令 \(f_i\) 表示把 \(x\) 除若干次得到 \(1\) 的最小操作次数,有:
答案即 \(f_x+f_y\)。由于状态数是 \(O(\sigma_0(x)+\sigma_0(y))\) 的,可以通过。用记忆化搜索实现比较好写,虽然最慢的点跑了 \(2968\mathrm{ms}\)。