主要考察的是对一段区间的维护,对区间维护的方法:前缀和,树状数组,线段树,st表,滑动窗口等等,我们一一进行筛选,发现此题要求为定区间,然后分析题意,题目给定的时间是单调递增的,所以可以使用滑动窗口,使用队列去进行实现,我们去存船的话,会发现很复杂,所以把目标看向人,我们维护不同国籍的人即可。
又因为i-1的情况对i是有贡献的,所以ans可以重复利用,不用每次置零
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef pair<int,int> pll;
typedef long long ll;
struct node {//结构体存人的国籍和到岸时间
int nt,tm;
};
int z[N];//用于维护国籍为i的人数
void solve()
{
int n;
cin>>n;
int ans=0;//ans记录答案
queue<node> q;
for(int i=0;i<n;i++){
int t,k;
cin>>t>>k;
while(k--){
int x;
cin>>x;
if(!z[x]){
ans++;//如果当前国籍没人,所以答案++
}
z[x]++;
q.push({x,t});
}
while(q.front().tm+86400<=t){//如果队首的时间不合法了
z[q.front().nt]--;
if(!z[q.front().nt]) ans--;//该国籍人数为0了,答案就要减1
q.pop();
}
cout<<ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
既然由本题提到了滑动窗口这一概念,那么就来看看滑动窗口。
滑动窗口,有两种维护方式吧,一种是双指针,另一种是单调队列,目前已知的是可以去维护窗口内的最大值,最小值,然后由这题可知,应该也可以去维护众数。
具体实现,可以手写也可以用stl的deque。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef pair<int,int> pll;
typedef long long ll;
void solve()
{
deque<pll> q,p;
int n,k;
cin>>n>>k;
vector<int> a(n+1);
for(int i=1 ;i<=n;i++) cin>>a[i];
vector<int> small,big;
for(int i=1;i<k;i++){
while(!q.empty()){
if(a[i]>q.back().first)
q.pop_back();
else break;
}
q.push_back({a[i],i});
while(!p.empty()){
if(a[i]<p.back().first) p.pop_back();
else break;
}
p.push_back({a[i],i});
while(!q.empty()){
auto x=q.front();
if(x.second+k<=i){
q.pop_front();
}
else{
break;
}
}
while(!p.empty()){
auto x=p.front();
if(x.second+k<=i) p.pop_front();
else break;
}
}
for(int i=k;i<=n;i++){
while(!q.empty()){
if(a[i]>q.back().first)
q.pop_back();
else break;
}
q.push_back({a[i],i});
while(!p.empty()){
if(a[i]<p.back().first) p.pop_back();
else break;
}
p.push_back({a[i],i});
while(!q.empty()){
auto x=q.front();
if(x.second+k<=i){
q.pop_front();
}
else{
break;
}
}
while(!p.empty()){
auto x=p.front();
if(x.second+k<=i) p.pop_front();
else break;
}
big.push_back(q.front().first);
small.push_back(p.front().first);
}
for(auto x: small ) cout<<x<<" ";
cout<<endl;
for(auto x: big ) cout<<x<<" ";
cout<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
// system("pause");
return 0;
}
感觉应该可以简化很多的,但就先这样了,最后给出一题可以进行练习。