They Are Everywhere
大B,年轻的口袋妖怪训练师,找到了一个由 n 间从左向右的房间组成的大房子。你可以从街道里走入任何一间房子,也可以从任何一间房子走到街道上。同时,你也可以从左边的一个房间走向右边的房间。房间 1 只和房间2相连 2 并且房间 n 只和房间 n - 1.相连。
在每个房间中恰好有一只某个种类的口袋妖怪,用一个大写或小写字母表示。现在大B要走入其中一间房间,向右走一些房间并捕捉所有路过的房间的口袋妖怪,之后再在某个房间出来。问大B至少要走多少个房间才能捕捉到所有种类的口袋妖怪?
Input
第一行包含一个整数 n (1 ≤ n ≤ 100 000) — 表示房间中口袋妖怪的数量。
第二行包含一个字符串 s 长度为 n,只包含大小写字母,第 i 个字符表示在第 i 个房间中的口袋妖怪种类。
Output
输出最少走过的房间数。
Example
Input
3
AaA
Output
2
Input
7
bcAAcbc
Output
3
Input
6
aaBCCe
Output
5
Note
第一个样例中从 1 走到 2。
第二个样例中从 4 走到 6.
第三个样例中从 2 走到 6.
sol:枚举右端点,对于一个右端点R,显然如果L满足区间[L,R]可以覆盖全部,[L-1,R]一定也可以,这样就可以二分了
复杂度玄学O(n*logn*52)一看就是CF能过的复杂度qaq
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar(' ') const int N=100005; int n; char S[N]; int Qzh[N][55]; int Need[55]; inline char Get(char ch) { if(islower(ch)) return ch-'a'; else return ch-'A'+26; } inline bool Judge(int Pos,int R) { int i; for(i=0;i<52;i++) if(Need[i]) { if(Qzh[R][i]-Qzh[Pos][i]==0) return false; } return true; } inline int Check(int ql,int qr,int R) { int l=ql,r=qr,mid; while(l<=r) { mid=(l+r)>>1; if(Judge(mid,R)) l=mid+1; else r=mid-1; } return r; } int main() { int i,j,ans; ans=n=read(); scanf("%s",S+1); for(i=1;i<=n;i++) { for(j=0;j<52;j++) Qzh[i][j]=Qzh[i-1][j]; Qzh[i][Get(S[i])]++; } for(i=0;i<52;i++) if(Qzh[n][i]) Need[i]=1; for(i=1;i<=n;i++) { bool Bo=0; for(j=0;j<52;j++) if(Need[j]&&(!Qzh[i][j])) {Bo=1; break;} if(!Bo) break; } for(;i<=n;i++) { int Pos=Check(0,i-1,i); ans=min(ans,i-Pos); } Wl(ans); return 0; } /* input 3 AaA output 2 */