摘要:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define rg register 6 #define N 200010 7 using namespace std; 8 阅读全文
摘要:
【题解】 我们可以发现每一对可以匹配的左右括号一定是一一对应的,那么我们用一个栈维护即可。如果当前是右括号,栈顶是左括号,那么一定有1的贡献,还要加上之前到达过top-1这个位置多少次,因为现在这一对括号可以和之前的那些组成更长的序列。 1 #include<cstdio> 2 #include<c 阅读全文
摘要:
【题解】 我们可以很快发现当n是奇数的时候答案就是n*(n-1)*(n-2),因为这三个数一定两两互质,因为它们中只有n-1是2的倍数,而其它数的倍数的周期都比3长,所以也不可能有别的大于2的公因数。当n是偶数的时候怎么办呢?当n不是3的倍数的时候答案是n*(n-1)*(n-3),这里避开(n-2) 阅读全文
摘要:
【题解】 设满足前后两个元素之差为1的最长上升子序列LIS的长度为m,那么本题的答案即为n-m. 证明: 1,n-m次移动一定可以让序列递增。设LIS的第一个数为i,最后一个数为j,我们按照i-1到1的递减的顺序把这些数调换到第一个位置,它们就排好序了。同理处理j+1到n. 总共需要n-m次移动。 阅读全文
摘要:
【题解】 排序,然后枚举前两个数,再用类似two pointer的思想扫第三个数即可,不需要二分。复杂度n方。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define LL lo 阅读全文
摘要:
【题解】 二重循环枚举起始列和终止列,竖着往下加,转化为一个最大子段和问题,逐行累加即可。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define N 1000 6 # 阅读全文
摘要:
【题解】 先把数字两两组合,问题转化为求a+b=0. 这个问题显然可以排序后two pointer做。需要注意选出来的两个数必须由4个不同位置的数组成,不能重复。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #defi 阅读全文
摘要:
【题解】 dp转移的时候记录一下,然后倒着推出答案即可。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define rg register 6 #define N 200 阅读全文
摘要:
【题解】 直接做树形DP即可。f[i]表示取i及其子树的最大的美丽指数,若某个儿子son满足f[son]>0,f[i]就加上f[son]. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long l 阅读全文
摘要:
【题意概述】 对一个1到n的排列做m次区间排序,最后询问位置q上面的数。 【题解】 区间排序的效率是nlogn,所以暴力做的话效率是mnlogn,显然达不到要求。 我们考虑二分答案。如果某个位置的数比mid小,就设为0,如果么某个位置的数大于等于mid,就设为1. check的时候我们只需对01序列 阅读全文
摘要:
【题解】 二分答案,贪心check. 然后根据二分出来的答案去计算每个人抄写的部分,注意要让前面的人少抄写,所以从后往前贪心即可。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 阅读全文
摘要:
【题解】 经典的最大子段和问题。如果当前sum大于等于0,就累加上当前的数;当前的sum小于0,就把sum变为0,即之前的那些都不取,因为它们对答案的贡献是负的。扫一遍即可。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 阅读全文
摘要:
【题解】 两个人面对面碰见,然后转身继续走,这一过程可以看做两个人对穿而过。那么这道题其实就是简单的贪心题,每个人选择远的一边走就可以求出最大值,反之可以求出最小值。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #de 阅读全文
摘要:
【题意概述】 给一棵以1为根的树,树上的每个节点有一个ai值,代表它可以传送到自己的ai倍祖先,如果不存在则传送出这棵树。现在询问某个节点传送出这棵树需要多少步。 【题解】 其实是把“弹飞绵羊”那道题从序列上搬到了树上,解法其实类似。 我们可以用LCT维护传送的关系,若点i存在ai倍祖先,那么就把他 阅读全文
摘要:
【题解】 区间DP. 设f[i][j]表示i~j的最小代价。再枚举中间点k,很容易想到转移方程为f[i][j]=min(f[i][j],f[i][k]+f[k][j]),同时如果i~k可以通过重复获得i~j,那么f[i][j]=min(f[i][j],f[i][k]+len(x)+2),这里的len 阅读全文
摘要:
【题意概述】 给出n个01串组成的字典和m个询问,每次询问某个01串和多少个字典中的串有相同的前缀。(前缀长度是两串中较小的部分) 【题解】 直接上Trie树即可。树上每个节点记录两个信息:这个节点有多少个串经过,这个节点是多少个串的结尾。 1 #include<cstdio> 2 #include 阅读全文
摘要:
【题解】 因为n很小,直接弗洛伊德就可以了。按照询问来做弗洛伊德,把两次询问之间新修好的点拿来当中继点,更新其他点的答案,并回答询问。 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long lon 阅读全文
摘要:
【题意概述】 有n只狼要杀,杀每只狼的代价是它的攻击值加上它相邻的存活的狼的附加值。求最小的代价。 【题解】 区间DP. 设f[i][j]为杀掉i~j的狼的最小代价,可以推出状态转移方程为f[i][j]=min(f[i][k]+f[k+1][j]+a[k]+b[i-1]+b[j+1]),枚举区间长度 阅读全文
摘要:
【题意概述】 有n个位置,每个位置可以放F或者M,规定一种合法的放置方案为不存在单独的F(即每个F的左边或者右边必须至少有一个F),问有多少种放置方案。 【题解】 假设有一种合法的放置方案,有n-1个位置,那么我们在末尾多放一个M,必定是一个合法的方案。(放F则不一定) 有n-2个位置的合法放置方案 阅读全文
摘要:
【题解】 暴力枚举添加字符的位置,然后判断去掉这个位置的字符串是否有由两个相同的串拼接而成。本题的n的范围为200W,暴力判断会TLE,所以要使用哈希。 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<m 阅读全文