题意:
- m朵花,从第一个开始,按顺序每k个做成一个花圈,一共要做n个。其中一个要满足条件:必须包含要求的s种。
- 移掉几朵花,使产生规定的花圈,并且可以做成n个。
题解:
- 先找到一个区间[l,r],满足r-l+1≥k并且有要求的s种花。并且前面的l-1朵花是k的倍数,如果不是,那么就要移走(l-1)%k朵花,也就是移走区间[(l-1)/k*k,l)的花。并且移走的花的数量要≤m-n*k。
代码:
#include <bits/stdc++.h>
using namespace std;
int const N = 500000 + 10;
int m,n,k,s,limit;
int a[N],b[N],need[N],num[N];
int main(){
scanf("%d%d%d%d",&m,&k,&n,&s);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
for(int i=1;i<=s;i++){
int tmp; scanf("%d",&tmp);
need[tmp]++;
}
int l = 1,r = 0,cnt = 0;
bool flag = false;
while(r < m && !flag){
while(r < m && (r - l + 1 < k || cnt < s)) //!(r - l + 1 >= k && cnt >= s)
if(++num[a[++r]] <= need[a[r]]) cnt++;
while(l <= r && (l - 1) % k + (r - l + 1) - k > m - n * k){
num[a[l++]]--;
if(num[a[l-1]] < need[a[l-1]]){
cnt--;
break;
}
}
if(cnt == s) flag = true;
}
if(!flag) printf("%d\n",-1);
else{
int res = m - n * k - (r - l + 1- k); //两侧要移走的花
printf("%d\n",m - n * k);
for(int i=(l-1)/k*k+1;i<l;i++) printf("%d ",i), res--;
cnt = 0;
for(int i=l;i<=r;i++){
if(r - l + 1 - cnt <= k) break;
if(need[a[i]] < num[a[i]])
printf("%d ",i), num[a[i]]--, cnt++;
}
for(int i=r+1;i<=m;i++) if(res) printf("%d ",i), res--;
}
return 0;
}