传送门 短代码神奇dp. 自己yy的思路居然1A了好高兴啊! 不难想到每个人选择的时候一定是取连续的最大的那一段数,自然需要先排序. 然后可以用dp[i]表示当前最大数是a[i]的时候先手可以获得的最优值. 不难想到dp[i]跟dp[1]~dp[i-1]都有关系,其实就是dp[i]=max(a[j]−dp[j−1])" role="presentation" style="position: relative;">dp[i]=max(a[j]−dp[…
传送门 一道感觉比较简单的dp. 注意是要求翻转一个子序列而不是一段连续的数(被坑了很多次啊)... 看到数据范围果断开一个四维数组来dp一波. 我们显然可以用f[i][j][k][t]表示下标在[l,r]内,值域在[k,t]之间且最多只会翻转一次能够生成的最长不下降子序列. 这不就简单了吗,从[l(+1),r(-1)]转移过来就三种情况. 第一种:该区间的值可以从[l+1,r]转移过来,如果a[l]=k的话对当前区间的贡献加1. 第二种:该区间的值可以从[l,r-1]转移过来,如果a[r]=t…
传送门 有趣的前缀和. 数据范围中的n≤200" role="presentation" style="position: relative;">n≤200n≤200提示我需要写出来一个O(n3)" role="presentation" style="position: relative;">O(n3)O(n3)的算法,思来想去感觉前缀和挺靠谱的于是写了写发现只有84,检查后发现把m打成了n(…
传送门 一道sb最短路,从两个起点和终点跑一边最短路之后直接枚举两人的汇合点求最小值就行了. 代码: #include<bits/stdc++.h> #define N 40005 #define inf 0x3f3f3f3f using namespace std; struct Node{int v,next;}e[N<<1]; int first[N],cnt=0,b,E,p,n,m,d[N][3]; bool vis[N]; inline void add(int u,in…
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头尾.然后开始逐位比较,当两个字串同一位置的字符不同时,相对来说字符值较大的指针跳到失配下标的后面一位,如果此时两个指针重合,将其中一个加一.边界条件:两个指针中有一个值大于原数组长度. 代码如下: #include<bits/stdc++.h> #define N 300005 using nam…
洛谷题面传送门 又是一道我不会的代码超短的题( 一开始想着用生成函数搞,结果怎么都搞不粗来/ll 首先不妨假设音阶之间存在顺序关系,最终答案除以 \(m!\) 即可. 本题个人认为一个比较亮的地方在于,每个音阶被奏响次数都是偶数这个条件的处理方式.由于是奇偶性,我们可以发现如果我们钦定了其中 \(m-1\) 个片段对应的音阶集合,那么第 \(m\) 个片段中的音阶集合一定已经确定了.我们考虑从这个性质入手.设 \(dp_i\) 表示有多少个包含 \(i\) 个片段且符合要求的音阶集合,那么我们考…
传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h> #define N 100005 #define Max 100000 using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigi…
传送门 fft模板题. 终于学会fft了. 这个方法真是神奇! 经过试验发现手写的complex快得多啊! 代码: #include<iostream> #include<cstdio> #include<cmath> #define N 10000005 using namespace std; inline int read(){ int ans=0,w=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')w=-…
传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二个地址为j,则有 total=[∑i=1ndis[i]∗w[i]]−dis[i]∗w[i]−dis[j]∗(sum[j]−sum[i])" role="presentation" style="position: relative;">total=[∑n…
传送门 题目就是要求维护带权重心. 因此破题的关键点自然就是带权重心的性质. 这时发现直接找带权重心是O(n)的,考虑优化方案. 发现点分树的树高是logn级别的,并且对于以u为根的树,带权重心要么就是u,要么存在于u的某一个儿子为根的子树中. 由于带权重心只有一个,因此只需要从根节点开始向下跳,跳不动了就是答案. 代码: #include<bits/stdc++.h> #define N 100005 #define ll long long using namespace std; inl…