ZROI2018提高day1t3】的更多相关文章

传送门 分析 考场上想到了先枚举p的长度,在枚举这个长度的所有子串,期望得分40~50pts,但是最终只得了20pts,这是因为我写的代码在验证中总是不断删除s'中的第一个p,而这种方式不能解决形如ababaa的字符串.于是我们考虑满分做法.设dp[i][j]表示在当前的p的情况下s的[i,j]位置是否满足.满足是指这一段区间只由p构成或者一部分只由p构成,另一部分则是p的前缀.对于位置j的字符可能有两种情况: 1.和之后数个字符拼成一段,转移: dp[i][j]|=(dp[i][j-1]&(s…
题目链接 设可能的答案串为p,长为len.p一定是s的一个子串且len|n. 虽然一些p在s中可能被断成若干段,但删掉其中的若干段后,这段区间一定会被全部消掉. 于是枚举p后,可以用f[i][j]表示区间[i,j]是否合法.len不需要整除区间长度,多余的部分要匹配p的前缀(匹配什么后缀啊,大不了从前面开始). f[i][j]可以由j-1拼,即 \(f[i][j]|=f[i][j-1]\ \&\&\ s[j]==p[(l-1)/l+1] (l=j-i+1)\). 也可以是j和前面构成了可消…
传送门 分析 我们首先想到的自然是根据大小关系建图,在这之后我们跑一遍拓扑排序 但是由于l和r的限制关系我们需要对传统的拓扑排序做一些改变 我们考虑将所有入度为0且现在的拓扑序号已经大于等于l的点放入一个优先队列,这个优先队列以r为关键字从小到大排序,这样我们就可以保证r小的点被排在前面 但是我们发现暴力判断l是否合法是行不通的,于是我们考虑再建一个优先队列,将所有入度为0的点以l为关键字从小到大排序,每次当队首l大于等于当前序号则弹出这个点,将这个点加入到r的那个优先队列中,这样我们就可以保证…
传送门 分析 将所有字母分别转化为1~26,之后将字符串的空位补全为0,?设为-1,我们设dp[p][c][le][ri]表示考虑le到ri个字符串且从第p位开始考虑,这一位最小填c的方案数,具体转移见代码. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #in…
传送门 分析 我们发现这个四元组可以分解成一个逆序对拼上一个顺序对,这个线段树搞搞然后乘一下就可以求出来了,但是我们发现可能有(a,b)为逆序对且(b,c)为顺序对的情况,所以要进行容斥,我们只需要枚举是哪一个点重合然后减掉即可. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cct…
传送门 分析我们可以根据性质将这个序列构造成一个环:0,a[1~n],0,a[n~1] 这中间的0是为了起间隔作用的. 我们又知道b[i]=a[i-1]^a[i+1] c[i]=b[i-1]^b[i+1]=a[i-2]^a[i]^a[i]^a[i+2]=a[i-2]^a[i+2] 所以如果这个环进化了2d次,则c[i]=a[i-2d]^a[i+2d] 所以我们二进制拆分一下就可以了. 代码 #include<iostream> #include<cstdio> #include&l…
传送门 分析 考场上傻了,写了个树剖还莫名weila...... 实际就是按顺序考虑每个点,然后从他往上找,一边走一边将走过的边染色,如果走到以前染过色的边就停下.对于每一个a[i]的答案就是之前走过的所有边的数量*2-它自己的深度. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<c…
传送门 分析 我们不难将条件转换为前缀和的形式,即 pre[i]>=pre[i-1]*2,pre[i]>0,pre[k]=n. 所以我们用dp[i][j]表示考虑到第i个数且pre[i]=j的情况下的方案数.我们发现一一转移的复杂度并不行,于是我们考虑只让dp[i-1][j]转移到dp[i][j*2],然后在利用前缀和的思想将dp[i][j]转移到dp[i][j+1],这样可以将复杂度优化到O(nk),然后使用滚动数组就可以了. 代码 #include<iostream> #inc…
传送门 分析 我们假设如果一个点是0则它的值为-1,如果一个点是1则值为1,则一个区间的答案便是max(pre[i]+sur[i]),这里的pre[i]表示此区间i点和它之前的的前缀的最大值,sur[i]表示i点之后的后缀最大值.所以为了维护每个区间的答案我们可以用线段树进行维护.而对于一个由两个区间拼成的区间它的答案只有三种 1. 由左区间所选的pre加上右区间的sur 2. 由左区间的全部加上右区间的pre和sur 3. 由左区间所选的pre和sur加上右区间的全部 而这个区间的答案即为这三…
传送门 分析 我们二分球的直径,然后就像奶酪那道题一样,将所有距离相遇直径的点用并查集连在一起,然后枚举所有与上边的顶距离小于直径的点和所有与下边的距离小于直径的点,如果它们被并查集连在一起则代表这个球无法通过.于是可以得到答案. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cct…