cf1121d 尺取

时间:2023-03-10 00:14:17
cf1121d 尺取

尺取,写起来有点麻烦

枚举左端点,然后找到右端点,,使得区间[l,r]里各种颜色花朵的数量满足b数组中各种花朵的数量,然后再judge区间[l,r]截取出后能否可以供剩下的n-1个人做花环

/*
给定序列A,分成n段,每段k个,
然后删掉A中的一些,但任要能组成n段,使得A中的一段包含序列B中的所有元素
如果可以输出删掉的元素,否则输出-1
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 500005
int m,k,n,s,a[maxn],b[maxn],c[maxn];
int tot[maxn],cnt[maxn];//tot[i]表示第i种颜色需要的数量
int l,r,sum,Max,all;
int judge(int l,int r){//判断除去l,r是否可行
int tmp1=l-,tmp2=m-r;
if(tmp1/k+tmp2/k+>=n)return ;
return ;
}
void add(int i){
if(cnt[a[i]]==)return;
tot[a[i]]++;
if(tot[a[i]]==cnt[a[i]])sum++;
}
void del(int i){
if(cnt[a[i]]==)return;
tot[a[i]]--;
if(tot[a[i]]==cnt[a[i]]-)sum--;
} int main(){
cin>>m>>k>>n>>s;
for(int i=;i<=m;i++)cin>>a[i],Max=max(Max,a[i]);
for(int i=;i<=s;i++)cin>>b[i],Max=max(Max,b[i]);
for(int i=;i<=s;i++)cnt[b[i]]++; l=,r=k;sum=;
for(int i=;i<=Max;i++)
if(cnt[i]!=)all++;
for(int i=l;i<=k;i++)
add(i); while(){
if(sum==all){
if(judge(l,r)){//可行
vector<int>v;
v.clear();
int tmp=r-l+;
for(int i=l;i<=r;i++){
if(cnt[a[i]]> || tmp==k)
cnt[a[i]]--;
else v.push_back(i),tmp--;
}
printf("%d\n",v.size());
for(int i=;i<v.size();i++)
printf("%d ",v[i]);
return ;
}
del(l);l++;
} while(sum<all || l+k->r){
r++;
if(r>m)break;
add(r);
}
if(r>m)break;
}
puts("-1");
}