1 条题解
-
0
假设选择 和 的人,当 向后移动的时候, 不可能向左移动,所以我们可以使用双指针解决。
维护一个队伍个数 ,对于一个 ,若 ,即人数大于队伍数,则 不合法,需要向后移动。
维护一个桶,每一次移动 或 的时候更新一下。如果加入一个元素前桶该位置为空,或删除一个元素后桶该位置为空,就要更新 。
注意 要从 开始, 从 开始。然后有一个 corner-case,就是 跳出 的范围,但 是合法的,此时也要更新答案。
#include<bits/stdc++.h> #define int long long #define R(x) x=read() using namespace std; inline int read() { int x=0,y=1; char e=getchar(); while(e<'0'||e>'9') { if(e=='-')y=-1; e=getchar(); } while(e>='0'&&e<='9') { x=(x<<1)+(x<<3)+(e^'0'); e=getchar(); } return x*y; } const int N=500005; int m,n,a[N]; int t[N]; signed main() { R(m),R(n); for(int i=1;i<=n;++i){ R(a[i])+1; ++t[a[i]]; } t[0]=114; int mx=0,cnt=m; pair<int,int>ans={0,0}; for(int l=0,r=1;l<=n;){ while(r<=n&&l+n-r+1>cnt){ --t[a[r]]; if(!t[a[r]]) --cnt; ++r; } if(r==n+1&&cnt==l&&l>mx){ mx=l; ans={l+1,n}; } if(r<=n&&l+n-r+1>mx){ ans={l+1,r-1}; mx=l+n-r+1; } ++l; if(!t[a[l]])++cnt; ++t[a[l]]; } cout<<ans.first-1<<" "<<ans.second-1; return 0; }
- 1
信息
- ID
- 10182
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者