CSUST - 2021 组队选拔赛
闲言 比赛链接:传送门 没有代码,放心食用。 A Find Subsequence (WA了一晚上,回来把树状数组重写了一下就过了???) 树状数组 + DP 令dp[i]表示前$i$个元素中,以a[i]结尾的只出现一次的子序列的数目。 a[i]在之前未出现过: $$dp[i]=1+\sum_{k=1}^{i-1}dp[k]$$ a[i]在之前出现过,考虑上一次出现的位置。显然当前位置使得上一次出现的位置之前的贡献变成$0$,同时处在区间$[last[a_i], i-1]$的贡献不改变。 $$dp[i]=\sum_{k=last[a_i]}^{i-1}dp[k]$$ dp[last[a[i]]]将变成0。 B operation ((a & b) + (a | b)) >> 1等价于(a + b) >> 1 最后一次合并可以等价为,将数组从中划分成两半,分别操作完后再合并 由于可能的答案很少,考虑枚举分割点记忆化搜索。 C 翻墙之旅 10.2组队训练有一样的题:Gym 103306A Alice Birthday SoSDP 令所有点构成的点集为$sn$,考虑一个包含点1的点集$s$,令f[s]表示使得$s$中只有一个连通分量的(点集内部的)删边方案数,cnt[s]表示点集$s$内的边数。在$s$中,点1一定能到达连通分量内的所有点,且此时外部的所有的边都可以选择删或者不删,那么该状态对$s$内的所有点的贡献即为$2^{cnt[sn-s]}\times f[s]$。 cnt[s]的计算不再赘述,关键讲f[s]: $s$内所有边的存在形式有$2^{cnt[s]}$种,减去有多个连通分量的情况即为只有一个连通分量的数目, $$2^{cnt[s]}-\sum_{s_0 \subset s} f[s_0]\times 2^{cnt[s-s_0]}$$ 使用SoSDP(子集DP)计算,为了避免重复计算,可以限定$s_0$中包含$s$的lowbit,或者其它的某点。 1 2 3 for (int s = 0; s < bit[n]; s++) for (int s0 = (s - 1) & s; s0; s0 = (s0 - 1) & s) if (s0 & (s & -s)) ....