T1:Doughnut:
解体情况:60pts,取模炸了。。加个mod再取模就AC;
题意:第一次到一个格子放一个甜甜圈,若这个格子内甜甜圈为奇数则跳到p[i](p[i]<=i),否则跳到i+1;
算法分析+解法;每次新到一个点或者回到原来走过的点这个点上的甜甜圈数都是奇数,需要一直递归到p[i]==i,而且每次到一个点且这个点甜甜圈数量为奇数要走到下一个点所需要的次数不变,由于p[i]<=i,可以用一个数组f[i]记录从i点且此时i点甜甜圈数量为奇数走到i+1需要多少次,则f[i]=∑i-1j=p[i]+2(需要从p[i]跳回i且i这个点放了两次),用前缀和维护f[i]即可。
实现效果:时间复杂度:O(n),空间复杂度(n),实际使用内存25524KB。
小结:
1.解题关键在于认识到一个点为奇数时走到下一个点需要的次数是定值;
2.带有减法的取模需要+mod再取模(多么痛的领悟)。
后续动作:写题养成仔细的习惯,以免发生写码五分钟,改码两小时的悲剧或者交上去都不知道怎么死的。
T2:解题情况:60pts,普通dp。
题意:求区间子串=“(0w0)”的个数(不包括引号),带区间修改。
算法分析+解法:
60pts:设f[i][j]为在原字符串中取到第i位,颜文字中取到第j位的方案数,if(s[i]==颜文字中第j位) f[i][j]=f[i-1][j]+f[i-1][j-1];
100pts: 线段树中定义f[i][j]为这一段区间中在颜文字中区间为i~j的方案数,修改就正常logn修改。查询的时候会发现,可能线段树中一个区间与另一个区间可以组成颜文字,而他们不在一个区间,没有f[i][j]记录跨区间的值,所以不能直接ans=∑t[p].f[1][5]。但是线段树的遍历有一个性质,就是先遍历左边在遍历右边,因此后遍历的一定在先遍历的右边,因此可以用一个数组存遍历到这个区间之前的方案数,现在的区间从之前遍历过的转移即可实现跨区间转移。
实现效果:时间复杂度:O(22*m*logn),空间复杂度(n),实际使用内存61524KB。
小结:(线段树数组开4倍!!Debug耗了半天)
解题关键:
1.线段树中dp(想到线段树,想到dp,没想到线段树中dp。。)
2.线段树的遍历顺序实现跨区间转移
后续动作:写题时拓宽思维广度,各种算法结合,不拘泥于一种算法。
T3:Tiramisu:
解题情况:0pts(本想用差分骗30pts,交上去RE。。)
题意:给一个0/1字符串,每次可以对长度为k的区间取反,问是否能是l~r区间全部变为0,能输出最少次数,不能输出-1.
算法分析+题解:我考试时用差分是用来优化这一位是1/0的,但是题解给出了一个更妙的解法:差分数组记录每一位与前一位异或值,若对k取模相等的一类数的差分数组值的和为奇数则无解(每一对对于k取模相等的差分为1的两个位置可以抵消),否则输出每一对位置差的和/k(一次操作会使左端点和右端点+1的位置取反,每一对位置需要抵消的次数为(r-l)/k),前缀和预处理答案,哈希判断是否有解,对于每一次询问左右端点特判。
实现效果:由于第二题的下饭操作没来得及实现
小结:
解题关键:找到差分(异或)的性质,即抵消一对差分的本质。
后续动作:写题时多读题,找性质,简化模型。
原文:https://www.cnblogs.com/oierqingmo/p/13520160.html