CodeForces - 958 F2 Lightsabers (medium) . (尺取法)
Posted 采蘑菇的小西佬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 958 F2 Lightsabers (medium) . (尺取法)相关的知识,希望对你有一定的参考价值。
题意:给你一个n和m,再给你一个长为n的序列和一个长为m的序列,问最少要删除多少元素,才能使第一个序列中的某个连续子串中恰好满足第二个序列对数字的要求
题解:尺取法,设l为左界,r为右界,若c[a[r]]==b[a[r]]则说明对b中第a[r]个数字的个数要求达到满足,则sum++。如果sum==m,则说明该子串满足条件,那么我们就要试图将左界前进(为了使删除要素更少,那么r-l+1肯定是最小的),此处注意要记得c[a[l]]减一,如果它在减之前的个数等于b[a[l]]则说明删减后,满足条件的个数减1,即sum-1
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <vector> #include <cstring> #include <iomanip> #include <set> #include<ctime> //CLOCKS_PER_SEC #define se second #define fi first #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define Pii pair<int,int> #define Pli pair<ll,int> #define ull unsigned long long #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0) const double Pi=3.14159265; const double e=2.71828182; const int N=3e5+5; const ull base=163; const int INF=0x3f3f3f3f; using namespace std; int a[N]; int b[N];int main(){ int n,m; fio; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; } int sum=0; int pp=0; for(int i=1;i<=m;i++){ cin>>b[i]; if(b[i]==0) sum++; pp+=b[i]; } int c[N]; int l=1,r=1; int MIN=INF; int op=0; for(;;){ while(r<=n&&sum<m){ c[a[r]]++; if(c[a[r]]==b[a[r]])sum++; r++; } if(sum<m)break; MIN=min(MIN,r-l-pp); if(c[a[l]]==b[a[l]])sum--; c[a[l]]--; l++; } if(MIN!=INF) cout<<MIN<<endl; else cout<<-1<<endl; return 0; }
以上是关于CodeForces - 958 F2 Lightsabers (medium) . (尺取法)的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 1610A Anti Light‘s Cell Guessing
CodeForces 1000B Light It Up(贪心思维)
CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT
Encryption (hard) CodeForces - 958C3 (树状数组)