CF190 D. Non-Secret Cypher
Question
给定一个长度为
n
n
n求满足
[
L
,
R
]
[L,R]
[L,R]中有至少
k
k
k个数字相同的子区间的数量。
1
≤
k
≤
n
≤
4
×
1
0
5
1\le k\le n \le 4\times 10^5
1≤k≤n≤4×105
Solution
遇到这种和
[
L
,
R
]
[L,R]
[L,R]有关的子区间数量问题,可以采取尺取法,尺取法每个边界判断一组,复杂度为
O
(
2
N
)
O(2N)
O(2N)即
O
(
N
)
O(N)
O(N),我们在尺取边界的同时,计入当前边界所能增加的贡献值即可。
当
[
L
,
R
]
[L,R]
[L,R]固定时,每次加上
n
−
R
+
1
n-R+1
n−R+1,因为
[
L
,
r
]
[L,r]
[L,r]在
r
∈
[
R
,
N
]
r\in [R,N]
r∈[R,N]时都满足。
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 4e5 +5;
int n,k,a[N];
map<int,int> M;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
int L=1,R=0;
bool ok=false;
ll ans=0;
while(R<=n){
if(ok){
ans+=n-R+1;
if(--M[a[L++]]==k-1) ok=false;
}else{
if(++M[a[++R]]==k) ok=true;
}
}
cout<<ans<<'\n';
return 0;
}