C++解题报告:连续的“包含”子串长度——(线段树+尺取法)
题目描述
区间查询和修改
给定N,K,M(N个整数序列,范围1~K,M次查询或修改)
如果是修改,则输入三个数,第一个数为1代表修改,第二个数为将N个数中第i个数做修改,第三个数为修改成这个数(例如1 3 5就是修改数组中第3个数,使之变为5)
如果是查询,则输入一个数2,查询N个数中包含1~K每一个数的最短连续子序列的长度
输入格式
第一行包含整数N、K和M(1 ≤ N,M ≤ 100000,1 ≤ K ≤ 50)
第二行输入N个数,用空格隔开,组成该数组
然后M行表示查询或修改
• “1 p v” - change the value of the pth number into v (1 ≤ p ≤ N,1 ≤ v ≤ K)
• “2” - what is the length of the shortest contiguous subarray of the array containing all the integers from 1 to K
输出格式
输出必须包含查询的答案,如果不存在则输出-1
样例
样例输入1
4 3 5 2 3 1 2 2 1 3 3 2 1 1 1 2
样例输出1
3 -1 4
样例输入2
6 3 6 1 2 3 2 1 1 2 1 2 1 2 1 4 1 1 6 2 2
样例输出2
3 3 4
思路详解
好题啊!!!(毒瘤,恶心。。。)
初步讨论
不用多说,看到区间马上想到线段树,而包含1到k每个数的最小子序列是个什么玩意儿???
接下来就要用尺取法了,想象两个指针curL和curR,不满足条件就将curR在区间上右移(扩大子序列),满足条件后再将curL向右移(缩小子序列),最后就可以得出答案(这个方法十分适用于连续区间和子序列之类的ÿ