Codeforces Round #543 (Div. 2) D 双指针 + 模拟
https://codeforces.com/contest/1121/problem/D
题意
给你一个m(<=5e5)个数的序列,选择删除某些数,使得剩下的数按每组k个数以此分成n组(n*k<=m),存在只要一组满足和目标集合s(|s|<=k)匹配(即集合中存在的数,组内一定存在)
题解
- 重点:找出至少一组满足要求的数
- 假设[l,r]内满足要求,还需要满足:\((l-1)/k*k+(m-r)/k*k>=k*(n-1)\),可以用双指针,对于每个l可以处理出最小的r满足要求
- 这样就把数组分成了三段[1,l-1],[l,r],[r+1,m],第一段[1,l-1]删除数字使得可以被k整除(没有限制随便删除),第二段[l,r]分成两种情况:
- (r-l+1)>k:去掉(r-l+1-k)个不符合要求的数
- (r-l+1)==k:不用删除任何数
坑点
- 对于第二段的第一种情况,不符合要求的数包括:
- 不在集合内的数
- 在集合内,但超出集合数量的数
- 模拟时应该优先删除不在集合内的数,并统计数目,数目不够再删除在集合内的数,假如优先删除在集合内的数,有可能会导致[l,r]内不符合要求
代码
#include<bits/stdc++.h>
#define M 500005
using namespace std;
int m,k,n,s,a[M],mp[M],x,kd,cnt,vi[M],l,r,ed,i,rm,CNT;
map<int,int>mk;
vector<int>ans;
int main(){
cin>>m>>k>>n>>s;
for(i=1;i<=m;i++)scanf("%d",&a[i]);
for(i=1;i<=s;i++){
scanf("%d",&x);
if(!mp[x]){kd++;}
mp[x]++;
}
cnt=0;
for(l=1;l<=m;){
while(cnt<kd&&r<=m){
vi[a[++r]]++;
if(vi[a[r]]==mp[a[r]])cnt++;
//if(vi[r]==mp[x]+1)cnt--;
}
if(r>m)break;
if(cnt==kd){
ed=max(l+k-1,r);
if(ed<=m){
if((l-1)/k+(m-ed)/k>=n-1){
rm=(l-1)%k;
for(i=1;i<=rm;i++)ans.push_back(i);
mk.clear();
if(r>l+k-1){
CNT=r-(l+k-1);
for(i=l;i<=ed;i++){
if(mp[a[i]]&&mk[a[i]]<mp[a[i]]){
mk[a[i]]++;
}else if(CNT){
ans.push_back(i);
CNT--;
}
}
}
printf("%d\n",ans.size());
for(i=0;i<ans.size();i++)
printf("%d ",ans[i]);
return 0;
}
}
}
if(vi[a[l]]==mp[a[l]])cnt--;
vi[a[l++]]--;
}
cout<<-1;
}
Codeforces Round #543 (Div. 2) D 双指针 + 模拟的更多相关文章
- Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)
http://codeforces.com/contest/1154/problem/E 解题: 举例n=10,k=1 1,2,10,4,7,6,9,8,5,3 第一次,1队先挑2,10,4这三个人 ...
- Codeforces Round #543 (Div. 2)B,C
https://codeforces.com/contest/1121 B 题意 给你n(<=1000)个数ai,找出最多对和相等的数,每个数只能用一次,且每个数保证各不相同 题解 重点:每个数 ...
- Codeforces Round #301 (Div. 2)(A,【模拟】B,【贪心构造】C,【DFS】)
A. Combination Lock time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...
- Codeforces Round #345 (Div. 2)【A.模拟,B,暴力,C,STL,容斥原理】
A. Joysticks time limit per test:1 second memory limit per test:256 megabytes input:standard input o ...
- Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)
A. Technogoblet of Fire 题意:n个人分别属于m个不同的学校 每个学校的最强者能够选中 黑客要使 k个他选中的可以稳被选 所以就为这k个人伪造学校 问最小需要伪造多少个 思路:记 ...
- Codeforces Round #544 (Div. 3) dp + 双指针
https://codeforces.com/contest/1133/problem/E 题意 给你n个数(n<=5000),你需要对其挑选并进行分组,总组数不能超过k(k<=5000) ...
- Codeforces Round #398 (Div. 2) A. Snacktower 模拟
A. Snacktower 题目连接: http://codeforces.com/contest/767/problem/A Description According to an old lege ...
- Codeforces Round #237 (Div. 2) B题模拟题
链接:http://codeforces.com/contest/404/problem/B B. Marathon time limit per test 1 second memory limit ...
- Codeforces Round #371 (Div. 2) C 大模拟
http://codeforces.com/contest/714/problem/C 题目大意:有t个询问,每个询问有三种操作 ①加入一个数值为a[i]的数字 ②消除一个数值为a[i]的数字 ③给一 ...
随机推荐
- vue 使用a+ router.push的形式跳转时,地址栏不显示参数
解决办法: a链接不要写href 属性
- cgi,fast-cgi,php-cgi,php-fpm转载详解
转载自:https://segmentfault.com/q/1010000000256516 首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编 ...
- JS 获取屏幕的宽度和高度,各种方式
Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document ...
- bean生命周期_Junit测试使用factory模式
在面试某互联网_保险 公司, 被问到了spring中bean的生命周期,不禁联想到我们之前作 junit测试时,使用了Factory模式,而没有用Mock.
- pthreads v3下的worker和pool的使用
有些人会想,明明用thread已经可以很好的工作了,为什么还要搞个worker和pool? 之所以要用到worker和pool还是因为效率,因为系统创建一个新线程代价是比较昂贵,每个创建的线程会复制当 ...
- golang语言中os/exec包的学习与使用
package main; import ( "os/exec" "fmt" "io/ioutil" "bytes" ) ...
- sqlserver window身份验证时切换账户的快捷键
sqlserver window身份验证时切换账户的快捷键:ctrl+alt_del
- Windows下PythonQt编译(vs2015+Qt5.11.2+PythonQt 3.2)探索
时间:2018年10月20日 笔者最近在做Qt方面的开发工作,需用到脚本程序对程序内部进行扩展,就很自然的想到了PythonQt,下面介绍PythonQt在Windows下的的安装编译心得,水平有限, ...
- 三种简单排序算法(java实现)
一.冒泡排序 算法思想:遍历待排序的数组,每次遍历比较相邻的两个元素,如果他们的排列顺序错误就交换他们的位置,经过一趟排序后,最大的元素会浮置数组的末端.重复操 作 ...
- C++基础教程(总结)
内容中包含 base64string 图片造成字符过多,拒绝显示