这周做的题目,难度总体都挺高的,集中在 CF 上 3000 左右。并且在通过之前没有看任何一题的题解!(得瑟一下!)其实,有些难题,多想想,还是能艹过去的!Try a Try, AC is OK.(bushi)至于为什么看这些 CF 评级比较高的题呢?因为感觉评分高一些的题,在题目风格上更加 OI 一些,也更是我所擅长的。
给定
$n,k,c$ ,以及长度为$n$ 的序列$a$ (保证元素互不相同)。操作
$k$ 次,每次随机选择一个$a_i$ ,然后将其$-1$ 。对于$x=0,1~...~2^c-1$ 输出最后序列的异或和为$x$ 的概率,答案对$998244353$ 取模。
$k,c\le 16,a_i\in [k,2^c),n\le 2^c-k$
洛谷题解区里的做法充斥着生成函数,的确看到这题想到的第一个想法就是二元生成函数:设
设一种最终局面中,第
我们注意到两个事情:1.复杂度实际上是
所以我们可以把东西序列分成若干段,在每个段内
由于
然后考虑如何把这
**评测链接:AC submission:https://codeforces.ml/contest/1408/submission/113971716. **
UPD:事后 zc_li 强神告诉我说直接对第二维 fwt 一下就行了,我傻了。
给定一个序列,求其中最长严格上升子序列长度及其个数。
序列按如下方式给出:给定
$n(1\leq n\leq 50)$ 和序列中的第一个数$x(-10^9\leq x\leq 10^9)$ ,接下来$n$ 个数$d_i(-10^9\leq d_i\leq 10^9)$ ,若$d_i\ge 0$ ,则重复$d_i$ 次,在序列末尾加上当前序列最后一个数$+1$ 的值,若$d_i<0$ ,重复$-d_i$ 次,在序列末尾加上当前序列最后一个数$-1$ 的值。
假如这个像过山车一样的序列总长只有
现在考虑序列可能很长的情况。我们发现:下降操作,大致相当于把
有没有合适的结构可以用来维护这个 DP 数组呢?有,那就是多项式!先给出一个结论:任一时刻的
- 序列
1,1,1,...
可以用$f(x)=1$ 表示。 - 它的前缀和可以用
$f(x)=\frac{(1+x)x}2$ 表示,它的前缀和的前缀和可以用$f(x)=\frac{(2x+1)(x+1)x}6$ 表示。...... 它的任意一阶前缀和都可以用多项式表示。 - 下降操作中,除了区间第一个数之外的
$f$ 可以用$f(x)+f(x-1)$ 表示;第一个数可以单独拆成一个常数多项式。 - 上升操作中,前缀和操作可以用多项式表示;而第一个数加上一个数,相当于在这个多项式上加上一个常数;而这些使得这段的
$f$ 可以看作是序列1,1,1,...
的多阶前缀和的多项式的和。
于是我们可以大力用多项式维护这个
有一些细节,比如在下降操作中,第一个位置需要单独新建一个多项式;上升操作中,如果有一段的
**评测链接:AC submission:https://codeforces.ml/problemset/submission/1474/113669336. **
有
$n$ 个灯笼拍成一排,第$i$ 个灯笼具有$p_i$ 的亮度。每个灯笼要么朝向左,照亮左边编号为$[i - p_i,i - 1]$ 的灯笼,要么朝向右,照亮右边编号为$[i + 1, i + p_i]$ 的灯笼。寻找一种方案,为所有的灯笼确定朝向,使得每一个灯笼被至少一个其他灯笼照亮。$n\le 3\times 10^5$。
Try a try,AC is OK!这里是
首先有一个
然后我们可以发现:同样的
但是还不能过,我们发现,对于同一个
for (int i = 1; i <= n; i++)
{
sort(dp[i - 1].begin(), dp[i - 1].end(), [](node x, node y) { return x.l == y.l ? x.r > y.r : x.l > y.l; });
int mx = -1e9;
for (int j = 0; j < dp[i - 1].size(); j++)
{
node u = dp[i - 1][j];
if (u.r <= mx) continue;
if (u.l >= i - p[i] && u.l != i) dp[i].push_back({ u.r < i ? i : n + 1, u.r, j, 0 });
dp[i].push_back({ min(u.l, u.r < i ? i : n + 1), max(u.r, i + p[i]), j, 1 });
mx = max(mx, u.r);
}
}
这样写,复杂度其实卡不满的,于是就过了。
**评测链接:AC submission:https://codeforces.ml/problemset/submission/1476/113486661. **
给定一个有向无环图,每条边都有
$W_i$ 的权重,给每个点分配权值$A_i$ ,对于每条连接$(u,v)$ 的边,定义其权值为$Bi=Au-Av$ ,要求:
$Bi>0$
$\sum Wi\cdot Bi$ 最小请输出一种
$A$ 的分配方案,$n\le 18$。
一开始可能会以为这个状态甚至可以按照拓扑序来贪心,但是最后一个样例就给出了反例——两条长短不同但是端点相同的链,这是不能直接贪心的。
那么我们考虑怎么 DP:一种朴素的状态设置是直接状压下已经填好的每一个点的权值,记为
由于
大开脑洞一下,我们费用提前计算,在
复杂度最劣是
**评测链接:AC submission:https://codeforces.ml/problemset/submission/1430/113711359. **
已知初始值$x=0$,给定下面2种命令:
set
$y$ $v$ ,令$x=y$,或花费$v$元钱删除该命令;if
$y$ ...end
,如果$x==y$,执行if...end
中的命令,否则跳过该if...end
。你需要使用最少的花费,使得无论运行到哪里,都有$x \neq s$。命令条数
$1e5$ 。
给人的直接感觉就是类似树形 DP,考虑设 if
,我们递归计算出这一个 if
内部的
**评测链接:AC submission:https://codeforces.ml/problemset/submission/1455/113822202. **
给出$n(1 \le n \le 200000)$个元素组成的序列$a_1,a_2,……,a_n$,求最长的子段使得其中有至少两个出现次数最多的元素。
假设每个元素的出现次数都比较少,我们可以枚举这个出现次数的上限
这样做为什么是对的?1. 这个最后选出的区间的
假设元素的取值范围很小怎么做呢?我们发现原数列的众数一定是这个子段的众数之一,证明使用反证法,设它不是,那么左移左端点,然后右移右端点,大众数和区间众数的出现次数会是两个相交的分段函数,也就意味着我总可以通过扩大区间使得众数包括大众数,并同时最优化答案;所以不为大众数的情况不存在。
我们枚举另一个众数是哪一个,我们只要找到这个数和大众数出现次数相同的极大区间即可,因为答案中的众数一定包括大众数,于是一旦与大众数相同,便一定是这个答案区间的众数;加入不是,那么它一定不是答案区间,并且存在长度更长的答案区间(证明同上)。
这时惊世骇俗的一步来了!我们分出现次数小于
这一题我想到了小于 Zenislt
大佬想到了大于
**评测链接:AC submission:https://codeforces.ml/problemset/submission/1446/113452417. **
你有
$26$ 个不同的字符,第$i$ 个字符有$c_i$ 个($\frac{n}{3} \leq c_i \leq n$)。你希望用这些字符,构造出一个字符串(每个字符在字符串中出现的个数不超过
$c_i$ ),使得这个字符串上不存在长度为奇数且大于$1$ 的回文串。求出方案数对$998244353$ 取模的结果。
这题是在补之前的题,所以有参考题解。
a
和 b
,于是设 a
和 b
、前两位是不是 a
或 b
(0/1/2)、前一位是不是 a
或 b
(0/1/2)。
于是就可以快乐
给你一个字符串
$s \pod {|S| \le 10^5}$ ,有$n \pod {n \le 10^5}$ 个询问,第$i$ 个询问包含一个整数$k_i$ 和一个字符串$m_i \pod {\sum_i |m_i| \le 10^5}$ 。要求找到一个字符串$t$ ,使得$t$ 是$s$ 的子串并且$m_i$ 至少在$t$ 中出现了$k_i$ 次。你只需要求出$t$ 的最短长度。保证
$m_i$ 互不相同。
把询问串建出 ACAM,然后遍历一遍
主要是十分感慨,感觉 FJOI 考场上写的也几乎是这份代码,只是把 ACAM 换成了 广义 SAM,我在想,倘若我没有看错题,那么考场上写的也许有就是这份代码了吧!那也许解决就与现在不同了吧!
写着写着,我感慨万分,但并不后悔或是遗憾;现在的我要做的,是拼搏拼搏再拼搏!
He Will come back soon.