文章目录

  • 尺取法 解题报告
    • PKU 2100 Graveyard Design
    • PKU 3061 Subsequence
    • PKU 2739 Sum of Consecutive Prime Numbers
    • PKU 3320 Jessica’s Reading Problem
    • HDU 2158 最短区间版大家来找碴
    • HDU 2369 Broken Keyboard
    • HDU 2668 Daydream
    • HDU 5672 String
    • HDU 5056 Boring count
    • HDU 6205 card card card
    • HDU 6103 Kirinriki
    • HDU 6119 小小粉丝度度熊
    • HDU 1937 Finding Seats
    • HDU 5178 pairs
    • PKU 2566 Bound Found
    • HDU 5806 NanoApe Loves Sequence Ⅱ


尺取法 解题报告

PKU 2100 Graveyard Design

链接:PKU 2100 Graveyard Design
题意:给定一个数 n ( n ≤ 1 0 14 ) n( n \le 10^{14}) n(n≤1014),求所有满足 n = ∑ k = i j k 2 n = \sum_{k=i}^{j} k^2 n=∑k=ij​k2 的 ( i , j ) (i,j) (i,j)。

  • 可以把 i , j i,j i,j 看成是 [ 1 , n ] [1, \sqrt n] [1,n ​] 内的数,并且永远满足 i ≤ j i \le j i≤j,维护一个区间平方和 s s s,然后执行如下操作:
  • 1)初始化令 s = 0 , i = 1 , j = 0 s=0, i=1,j=0 s=0,i=1,j=0;
  • 2)自增 j j j,并且令 s = s + j 2 s = s + j^2 s=s+j2;
  • 3)若 s > n s > n s>n,则 s = s − i 2 s = s - i^2 s=s−i2, i i i 自增;重复这一步直到 s < = n s <= n s<=n 满足后跳 3);
  • 4)若 s = n s = n s=n,则当前的 ( i , j ) (i, j) (i,j) 是一组可行解,记录;
  • 5)回到 2);
  • 最后输出所有可行解。

PKU 3061 Subsequence

链接:PKU 3061 Subsequence
题意:给定 n ( n < 1 0 5 ) n (n \lt 10^5) n(n<105) 个正数 a i ( a i ≤ 1 0 4 ) a_i ( a_i \le 10^4) ai​(ai​≤104) 和一个正数 p ( p < 1 0 8 ) p(p < 10^8) p(p<108)。找到一个最短的连续子序列,满足它的和 s ≥ p s \ge p s≥p。

  • 可以把 i , j i,j i,j 看成是 [ 1 , n ] [1, n] [1,n] 的下标,并且永远满足 i ≤ j i \le j i≤j,维护一个区间和 s s s,然后执行如下操作:
  • 1)初始化令 s = 0 , i = 1 , j = 0 s=0, i=1,j=0 s=0,i=1,j=0;
  • 2)自增 j j j,并且令 s = s + a j s = s + a_j s=s+aj​;
  • 3)若 s ≥ n s \ge n s≥n,更新可行解 ( i , j ) (i, j) (i,j),则 s = s − a i s = s - a_i s=s−ai​, i i i 自增;重复这一步直到 s < n s < n s<n 满足后跳 2);
  • 最后输出长度最小的可行解。

PKU 2739 Sum of Consecutive Prime Numbers

链接:PKU 2739 Sum of Consecutive Prime Numbers
题意:给定一个数 n ( n ≤ 1 0 4 ) n(n \le 10^4) n(n≤104),求所有满足 n = ∑ k = i j p k n = \sum_{k=i}^j p_k n=∑k=ij​pk​ 的 ( i , j ) (i,j) (i,j) 的对数(其中 p k p_k pk​ 代表第 k k k 个素数)。

  • 可以把 i , j i,j i,j 看成是第几个素数的下标,维护一个素数和 s s s,然后执行如下操作:
  • 1)筛选素数 p i p_i pi​ 后,初始化令 s = 0 , i = 1 , j = 0 s=0, i=1,j=0 s=0,i=1,j=0;
  • 2)自增 j j j,并且令 s = s + p j s = s + p_j s=s+pj​;
  • 3)若 s > n s > n s>n,则 s = s − p i s = s - p_i s=s−pi​, i i i 自增;重复这一步直到 s < = n s <= n s<=n 满足后跳 3);
  • 4)若 s = n s = n s=n,则当前的 ( i , j ) (i, j) (i,j) 是一组可行解,记录计数器 c n t cnt cnt;
  • 5)回到 2);
  • 最后输出计数器 c n t cnt cnt 即可。

PKU 3320 Jessica’s Reading Problem

链接:PKU 3320 Jessica’s Reading Problem
题意:给定 n ( 10 < n < 100000 ) n (10 \lt n \lt 100000) n(10<n<100000) 个数 a i ( a < 2 31 ) a_i ( a \lt 2^{31}) ai​(a<231) 。找到一个最短的连续子序列,满足它包含所有的数。

  • 首先把所有的数进行离散化,使得每个数都能准确映射到下标 [ 1 , t ] [1,t] [1,t];
  • 然后把 i , j i,j i,j 看成是第 i i i个数的下标,维护一个哈希表,然后执行如下操作:
  • 1)初始化令 s = 0 , i = 1 , j = 0 s=0, i=1,j=0 s=0,i=1,j=0;
  • 2)自增 j j j,并且自增 h a s h [ a j ] hash[ a_j ] hash[aj​],如果 h a s h [ a j ] = 1 hash[ a_j ]=1 hash[aj​]=1 则自增 s s s;
  • 3)若 s = t s = t s=t,记录 ( i , j ) (i,j) (i,j) 作为其中一个可行解,并且自减 h a s h [ a i ] hash[ a_i ] hash[ai​], i i i 自增;如果 h a s h [ a i ] = 0 hash[ a_i ]=0 hash[ai​]=0,则自减 s s s,重复这一步直到 s < t s < t s<t 则跳 2);
  • 最后输出长度最小的 ( i , j ) (i,j) (i,j) 即可。

HDU 2158 最短区间版大家来找碴

链接:HDU 2158 最短区间版大家来找碴
PKU 3320 Jessica’s Reading Problem 加强版,做法类似。

HDU 2369 Broken Keyboard

链接:HDU 2369 Broken Keyboard
题意:给定一个长度为 n ( n ≤ 1 0 6 ) n(n \le 10^6) n(n≤106) 的字符串 和 m m m,求不同字符数不超过 m m m 最长子串。

  • 可以把 i , j i,j i,j 看成是第几个字符的下标,维护一个哈希表 h a s h hash hash,然后执行如下操作:
  • 1)初始化令 s = 0 , i = 1 , j = 0 s=0, i=1,j=0 s=0,i=1,j=0;
  • 2)自增 j j j,并且自增 h a s h [ a j ] hash[ a_j ] hash[aj​],如果 h a s h [ a j ] = 1 hash[ a_j ]=1 hash[aj​]=1 则自增 s s s;
  • 3)若 s > n s > n s>n,自减 h a s h [ a i ] hash[ a_i ] hash[ai​], i i i 自增;如果 h a s h [ a i ] = 0 hash[ a_i ]=0 hash[ai​]=0,则自减 s s s,重复这一步直到 s ≤ n s \le n s≤n;
  • 4)若 s ≤ n s \le n s≤n,则当前的 ( i , j ) (i, j) (i,j) 是一组可行解,记录最大值;
  • 5)回到 2);
  • 最后输出最大区间的值即可。

HDU 2668 Daydream

链接:HDU 2668 Daydream
题意:给定一个长度为 n ( n ≤ 1 0 7 ) n(n \le 10^7) n(n≤107) 的字符串,求所有字符都不相同的最长子串。

  • 可以把 i , j i,j i,j 看成是第几个字符的下标,维护一个哈希表 h a s h hash hash,然后执行如下操作:
  • 1)初始化令 i = 0 , j = − 1 i=0,j=-1 i=0,j=−1;
  • 2)自增 j j j,并且自增 h a s h [ a j ] hash[ a_j ] hash[aj​];
  • 3)如果 h a s h [ a j ] > 1 hash[ a_j ] \gt 1 hash[aj​]>1 ,则自减 h a s h [ a i ] hash[ a_i ] hash[ai​], i i i 自增;
  • 4)如果 h a s h [ a j ] = 1 hash[ a_j] = 1 hash[aj​]=1,则更新 ( i , j ) (i, j) (i,j) 长度;
  • 5)回到 2);
  • 最后输出最大的区间的值即可。

HDU 5672 String

链接:HDU 5672 String
题意:给定一个长度为 n ( 10 ≤ n ≤ 1 0 6 ) n( 10 \le n \le 10^6) n(10≤n≤106) 字符串 s s s,问有多少子串包含至少 k ( 1 ≤ k ≤ 26 ) k(1 \le k \le 26) k(1≤k≤26) 个不同字符。

  • 用两个指针 ( i , j ) (i, j) (i,j) 代表某个阶段下子串指向的下标;
  • 对于某个子串,如果已经有 k k k 个不同字符,那么当前的区间 ( i , j ) (i, j) (i,j) 一定是满足条件的子串,并且 ( i , j + 1 ) , ( i , j + 2 ) , ( i , l e n − 1 ) (i, j+1),(i, j+2),(i, len-1) (i,j+1),(i,j+2),(i,len−1) 也都是满足条件的子串,计数器加 l e n − j len - j len−j;
  • 然后自增 i i i 继续判断可行性即可。

HDU 5056 Boring count

链接:HDU 5056 Boring count
题意:对于一个字符串,如果它的每个字母数都小于等于 k k k,则称其为 g o o d good good 串。给定一个长度为 s ( 1 ≤ s ≤ 1 0 5 ) s(1 \le s \le 10^5) s(1≤s≤105) 且只包含小写字母的字符串,求它的 g o o d good good 串的数量。

  • 用两个指针 ( i , j ) (i, j) (i,j) 代表某个阶段下子串指向的下标;
  • 如果某个子串 s [ i : j ] s[i: j] s[i:j] 满足条件,那么可以得出:以 j j j 为右端点的情况下,左端点只要大于等于 i i i,那么这个串一定是 g o o d good good 串,所以以 j j j 为右端点,满足条件的个数为 j − i + 1 j-i+1 j−i+1;
  • 所以整个调整过程就是: j j j 自增的过程,如果满足每个字母数都小于等于 k k k 的情况下,累加 j − i + 1 j - i + 1 j−i+1;否则,自增 i i i,继续判断可行性。

HDU 6205 card card card

链接:HDU 6205 card card card
题意:给定一个 n ( n ≤ 1 0 6 ) n( n \le 10^6 ) n(n≤106) 个元素的环形序列,求它的最大子序列。

  • 由于是环形的,所以可以先拷贝一份,然后进行双指针 ( i , j ) (i, j) (i,j) 移动,只有当条件满足时左指针才右移,条件为:
  • 求和小于零 或者 j − i + 1 > n j-i+1 \gt n j−i+1>n;
  • 中途记录最大值即可。

HDU 6103 Kirinriki

链接:HDU 6103 Kirinriki
题意:定义两个长度均为 n ( n ≤ 5000 ) n (n \le 5000) n(n≤5000) 的字符串的距离为: d i s A , B = ∑ i = 0 n − 1 ∣ A i − B n − 1 − i ∣ dis_{A,B} = \sum_{i=0}^{n-1} | A_i - B_{n-1-i}| disA,B​=i=0∑n−1​∣Ai​−Bn−1−i​∣求找出最长的两个子串,满足他们不相交,且距离小于等于 m m m。

  • 朴素方法为枚举长度,然后 A A A 串的起点, B B B 串的终点,模拟算一遍得出最优解,算法时间复杂度 O ( n 4 ) O(n^4) O(n4)。
  • 定义两个双指针 ( a l , a r ) (a_l, a_r) (al​,ar​), ( b l , b r ) (b_l, b_r) (bl​,br​);
  • 1)枚举 k = n − 1 → 0 k = n-1 \to 0 k=n−1→0
  • 2)初始化 d = 0 d = 0 d=0, a l = 0 , a r = − 1 a_l=0, a_r=-1 al​=0,ar​=−1 并且向右移动 a r a_r ar​ 指针; b r = k , b l = k + 1 b_r=k, b_l = k+1 br​=k,bl​=k+1 并且向左移动 b l b_l bl​ 指针;
  • 3)每次 a r a_r ar​ 指针 右移, b l b_l bl​ 指针左移,如果 b l > a r b_l \gt a_r bl​>ar​ 则 d = d + d i s ( A a r , B b l ) d = d + dis(A_{a_r}, B_{b_l}) d=d+dis(Aar​​,Bbl​​);否则跳出循环,回到 2);
  • 4)如果 d > m d \gt m d>m, d = d − d i s ( A a l , B b r ) d = d - dis(A_{a_l}, B_{b_r}) d=d−dis(Aal​​,Bbr​​),并且 a l a_l al​ 右移, b r b_r br​ 指针左移;
  • 5)如果 d ≤ m d \le m d≤m,则更新当前 m a x l e n = m a x ( m a x l e n , a r − a l + 1 ) maxlen = max(maxlen, a_r - a_l + 1) maxlen=max(maxlen,ar​−al​+1) 为最优长度。
  • 然后把字符串反序,再做一次如上操作。
  • 最后,输出 m a x l e n maxlen maxlen 即可。

HDU 6119 小小粉丝度度熊

链接:HDU 6119 小小粉丝度度熊
题意:给定 n ( n ≤ 1 0 5 ) n(n \le 10^5) n(n≤105) 个区间,区间之间可能重叠,现在给出 m m m 个数,希望把区间补成连续区间,问最多能够补成多大的连续区间。

  • 首先,先按照区间左端点排序,然后利用贪心将所有区间转换成不相交区间;
  • 然后计算相邻两个不相交区间之间需要补多少数,可以利用前缀和,用 O ( 1 ) O(1) O(1) 的时间求出 [ i , j ] [i, j] [i,j] 区间之间要补多少数才能连续,然后利用双指针进行求和单调性求解即可。

HDU 1937 Finding Seats

链接:HDU 1937 Finding Seats
题意:给定一个 n × m ( n , m ≤ 300 ) n \times m (n,m \le 300) n×m(n,m≤300) 的 01 矩阵和一个数,求一个面积最小的子矩阵,保证它和大于等于 k k k 。

  • 首先用 s u m i j sum_{ij} sumij​ 计算出矩阵的前缀和。
  • 枚举 l , r l,r l,r 作为子矩阵的左右端点,然后对上下端点采用双指针,从而转化成一维的求和单调性问题。

HDU 5178 pairs

链接:HDU 5178 pairs
题意:在 x x x 轴上有 n n n 个点 ( x i , 0 ) ( i = 0 , 1 , 2 , … , n − 1 ) (x_i,0)(i=0,1,2,…,n−1) (xi​,0)(i=0,1,2,…,n−1),求有多少整数对 ( a , b ) (a,b) (a,b) 满足 ∣ x b − x a ∣ ≤ k ( a < b ) |x_b−x_a| \le k (a \lt b) ∣xb​−xa​∣≤k(a<b)。

  • 首先对所有数按照 x x x 轴递增排序;
  • 然后用两个指针 ( i , j ) (i, j) (i,j) 代表下标,并且不断自增 j j j 下标;
  • 当 x j − x i > k x_j - x_i \gt k xj​−xi​>k 时,自增 i i i 下标;否则以 j j j 结尾的满足条件的区间个数就是 j − i j-i j−i,直接累加;

PKU 2566 Bound Found

链接:PKU 2566 Bound Found
题意:给定一个 n ( n ≤ 100000 ) n ( n \le 100000 ) n(n≤100000) 和 k k k,然后是 n n n 个数字 x i ( ∣ x i ∣ ≤ 10000 ) x_i ( | x_i | \le 10000) xi​(∣xi​∣≤10000) 组成的序列,再给出 k k k 个数 t l t_l tl​,要求对于每个 t l t_l tl​,求出绝对值最接近 t l t_l tl​ 的区间。

  • 尺取法的前提是满足单调性, x i x_i xi​ 有可能是负数,所以这题需要进行一个思路转换。
  • 首先记录下前缀和 s u m i sum_i sumi​,注意,需要将 s u m 0 = 0 sum_0 = 0 sum0​=0 也加入进来。
  • 问题就转变成了求满足条件 ∣ s u m j − s u m i ∣ < t l | sum_j - sum_i | < t_l ∣sumj​−sumi​∣<tl​ 的最大的 ∣ s u m j − s u m i ∣ | sum_j - sum_i | ∣sumj​−sumi​∣,这时候需要满足的是 i < j i \lt j i<j,如果能够做到 s u m i < s u m j sum_i < sum_j sumi​<sumj​ 恒成立,那么我们就可以采用尺取法了。
  • 所以可以对前缀和进行排序,注意排序的时候需要记录下原下标。
  • 然后就是对排序后的数组 s u m i sum_i sumi​ 进行尺取法了。

HDU 5806 NanoApe Loves Sequence Ⅱ

链接:HDU 5806 NanoApe Loves Sequence Ⅱ
题意:给定 n ( n ≤ 200000 ) n ( n \le 200000) n(n≤200000) 个数,求第 k k k 大的数 ≥ m \ge m ≥m 的区间的个数。

  • 将原数组中 ≥ m \ge m ≥m 的数变成 1,其它为 0,然后求出前缀和 s u m i sum_i sumi​。
  • 利用尺取法维护两个指针 ( i , j ) (i, j) (i,j),如果某种情况下 s u m j − s u m i ≥ k sum_{j} - sum_{i} \ge k sumj​−sumi​≥k,则所有区间 [ i + 1 , k ] ( j ≥ k ≥ n ) [i+1, k] (j \ge k \ge n) [i+1,k](j≥k≥n) 都满足上文所给的条件。所有以 i + 1 i+1 i+1 为左端点的满足条件区间数就是 n − j + 1 n-j+1 n−j+1 个;累加到答案。
  • 并且 s u m j − s u m i ≥ k sum_{j} - sum_{i} \ge k sumj​−sumi​≥k 时,左指针 i i i 自增。

解题报告 (十三) 尺取法相关推荐

  1. ACM常用的解题技巧:尺取法

    常用的解题技巧:尺取法 尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案.之所以需要 ...

  2. ACM常用的解题技巧:尺取法及相关例题

    常用的解题技巧:尺取法 尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案.之所以需要 ...

  3. 【HDU - 5672】String(尺取法)

    题干: There is a string SS.SS only contain lower case English character.(10≤length(S)≤1,000,000)(10≤le ...

  4. 【牛客161 - A】字符串(尺取法,桶标记法)

    题干: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 小N现在有一个字符串S.他把这这个字符 ...

  5. 【HDU - 5056】Boring count (尺取法)

    题干: You are given a string S consisting of lowercase letters, and your task is counting the number o ...

  6. ACM尺取法常见题解

    大佬博客地址 常用的解题技巧:尺取法 尺取法:顾名思义,像尺子一样取一段,借用挑战书上面的话说,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答 ...

  7. 解题报告(十三)中国剩余定理(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  8. 【2022第十三届蓝桥杯】c/c++ 大学c组 解题报告

    大家好,我是小单同学,欢迎交流指正~  今天上午蓝桥杯圆满落幕,准备了几个月的比赛也终于打完了.今年填空题变成了两道,同学们反映今年难度上升很大,小单也感觉今年难度较大hh,空了两道题.现在给大家分享 ...

  9. Codeforces Round #697 (Div. 3)A~G解题报告

    Codeforces Round #697 (Div. 3)A~G解题报告 题 A Odd Divisor 题目介绍 解题思路 乍一想本题,感觉有点迷迷糊糊,但是证难则反,直接考虑没有奇数因子的情况, ...

最新文章

  1. 编程指南_今晚7点,译者编程入门指南抽奖!
  2. synchronsized修饰方法的使用
  3. java京东查询物流轨迹事例_Java爬虫实现京东物流查询
  4. 揭秘 MWU 最佳画质游戏《永劫无间》技术历程
  5. win32窗口机制之CreateWindow
  6. react复制内容到剪贴板
  7. 客户将数据库迁移上云的常用办法
  8. php 随机颜色,php生成随机颜色的代码实例
  9. Python猫荐书系列:文也深度学习,理也深度学习
  10. firefox使用掘金插件_久等了,这款知名浏览器下载插件终于上线Chrome版本!
  11. 使用Tushare库下载股票数据
  12. iChart--组件定制
  13. VBA-Excel重心法求解最优地址
  14. 3D平面SLAM相关总结与思考
  15. 象棋军师app已经上线
  16. 软件包没有可安装候选
  17. 抑郁症自测量表测试软件,抑郁自评:医用抑郁自测量表,快来测一测你的抑郁指数是多少...
  18. Android实现支付宝AR功能,Android接入支付宝实现支付功能实例
  19. 王坤杨第十二周个人学习及生活情况总结
  20. csv文件查找指定内容

热门文章

  1. 公众号批量移动用户分组
  2. 基于TIA博途的顺序队列(FIFO)先进先出SCL算法程序(V15版本)
  3. java细节知识点学习1
  4. oracle 表在线重建,大表在线重建索引的考虑和碰到的限制问题-ORA-1450
  5. 趋势交易中区间跨度的定义
  6. NLP中面向文本表示的模型梳理
  7. Matlab-RBF网络(径向基函数网络)-rbepnngrnn
  8. JS鼠标滑过图片时切换图片
  9. 2022年测绘资质怎么办理及办理流程?
  10. [P3975][TJOI2015]弦论(后缀数组)