摘要:
这道题$O(n^2)$的dp是很好想的。 设$f_i$表示到$i$时的队伍小于等于$rank_i$最大的不用移动的个数,那么显然状态转移方程是 \(f_i=\max\limits_{j=1}^{j\leq i\&rank_j\leq rank_i}f_j+1\) 就是从小于等于一定不用乱序的转移。 阅读全文
摘要:
题面传送门 首先你可以把所有直径求出来然后暴力。 但是这道题可以把求树的直径的方法。 首先求出一条直径,把直径上的所有点点权减一。然后再求一遍,两次相减就是答案。 正确性显然。 代码实现: #include<cstdio> #include<cstring> #define max(a,b) ((a 阅读全文
摘要:
题面传送门 启发式合并大法好! 你会发现这道题可以暴力合并。 然而数据稍微用心一点就卡掉了。 然后你可以试图优化一下,比如合并时把小的合并到大的上面去。 结果就过了。 这样复杂度上界是$O(nlogn)$,具体证明在这篇题解里有。 代码实现: #include<cstdio> #include<cs 阅读全文
摘要:
用脚找一下规律就会发现可以构成最后一项为全部异或和的循环节。 那么前缀异或就好了。 代码实现: #include<cstdio> using namespace std; int n,m,k,z; long long a[1000039],q[1000039],ans,x,y; int main() 阅读全文
摘要:
看到数据范围一眼状压。 然后就是怎么转移的问题了。 设$f_i$为使用状态为$i$时所用的节点数。 然后你会发现这个用$O(2nnk)$的转移不了。 那么就可以枚举子集转移。 $dp$方程为$dp_i=min{dp_j+dp_{i⨁j}-lcp(i)}$ 复杂度$O(3^n)$ 代码实现: #inc 阅读全文
摘要:
当然这道题可以跑最小生成树。 但是那样时间复杂度是$O(nmα(n))$,可以被卡掉。 这里有一个跑不满$O(nm)$的 就是每次拿到一条边,就搜索是否联通。 不连通就加上去 联通就找到最大的那条边,看看能不能替换,能换就换。 代码实现: #include<cstdio> #include<cstr 阅读全文