I used something like a monotonous queue...
Sort the position of each vertex in the sequence and the position of a record. Sort the priority by first a and then the position ~~ In this way, the points with the same a will be obtained together .. in addition, it is combined from small to large according to the initial position... this makes it easy to see that when the question is to require at least k sub-sequences to be in the same phase .. if point [I] a = point [I + k-1] a and point [I] Mark the original location ~ Point [I + k-1] marking the original position is a viable range... find These intervals .. record the start and end points of these intervals .. this type of interval is characterized by a with exactly k starting points from the start point to the end point...
The rest is to traverse the original series... it is obviously the minimum end point of the interval that must meet the conditions .. this condition indicates that the start point of the interval is behind the current vertex or the current vertex .. start and end these intervals with priority from small to large .. otherwise, the starting point is from small to large... point a pointer to the header of the sorted interval .. the current condition is not met .. that is, the starting point of an interval is smaller than the current vertex .. it will inevitably be invalid later .. therefore, the invalid range is first removed from the team header .. until the start point of the current interval is behind the current vertex or the current vertex... at this time, we can find the nearest point from the current point, and k are the same .. it is clear that the part that is sent from the current point to the end of this area also meets the requirements (including this area ).. so .. the result is displayed ..
It seems that the logic is still a bit confusing ~~ Check the code ~~ Pretty clear ..
Program:
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <stdio. h>
# Include <string. h>
# Include <cmath>
# Include <queue>
# Define OOS 2000000000
# Define ll long
Using namespace std;
Struct node
{
Int w, d;
} Point [2, 500000];
Struct node1
{
Int s, e;
} H [500000];
Ll ans;
Bool cmp1 (node a, node B)
{
If (a. d! = B. d) return a. d <B. d;
Return a. w <B. w;
}
Bool cmp2 (node1 a, node1 B)
{
If (a. e! = B. e) return a. e <B. e;
Return a. s <B. s;
}
Int main ()
{
Int I, k, n, x, m;
Scanf ("% d", & n, & k );
For (I = 1; I <= n; I ++)
{
Point [I]. w = I;
Scanf ("% d", & point [I]. d );
}
Sort (point + 1, point + 1 + n, cmp1 );
M = 0;
For (I = 1; I <= n; I ++)
{
X = I + k-1;
If (x <= n & point [x]. d = point [I]. d)
{
M ++;
H [m]. s = point [I]. w;
H [m]. e = point [x]. w;
}
}
Sort (h + 1, h + 1 + m, cmp2 );
Ans = 0;
X = 1;
For (I = 1; I <= n; I ++)
{
While (h [x]. s <I & x <= m) x ++;
If (x> m) break;
Ans + = n-h [x]. e + 1;
}
Printf ("% I64d \ n", ans );
Return 0;
}