CF888C K-Dominant Character 題解
阿新 • • 發佈:2019-01-07
樓上的 題解太強了,本菜雞來說一說其他做法
這個題目看到的第一感覺就是二分答案,因為又是要求最小值且答案有單調性
設 ,二分最小的 ,然後 的掃出每個字串,把每個字串的字元資訊儲存,然後判斷每一個字串是否有公共字元。
我們發現這樣做有一些浪費時間,因為每個字串的字元資訊是不會變的,於是我們可以把它字首和記錄一下
表示前i個字元字元j出現的次數,然後列舉字串起點 和終點 ,每個字元出現的次數就是 就好了
優化完的時間複雜度為
才 這。。。二分也能過,出題人tql
#include <map>
#include <set>
#include <ctime>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <bitset>
#include <cstdio>
#include <cctype>
#include <string>
#include <cstring>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std ;
#define rep(i, a, b) for (int (i) = (a); (i) <= (b); (i)++)
#define per(i, a, b) for (int (i) = (a); (i) >= (b); (i)--)
#define clr(a) memset(a, 0, sizeof(a))
#define ass(a, sum) memset(a, sum, sizeof(a))
#define lowbit(x) (x & -x)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define enter cout << endl
#define siz(x) ((int)x.size())
typedef long long ll ;
typedef unsigned long long ull ;
typedef vector <int> vi ;
typedef pair <int, int> pii ;
typedef map <int, int> mii ;
typedef map <string, int> msi ;
const int N = 100010 ;
const int M = 30 ;
const int INF = 0x3f3f3f3f ;
const int iinf = 1 << 30 ;
const ll linf = 2e18 ;
const int MOD = 1000000007 ;
void print(int x) { cout << x << endl ; exit(0) ; }
void PRINT(string x) { cout << x << endl ; exit(0) ; }
void douout(double x){ printf("%lf\n", x + 0.0000000001) ; }
int a[M], b[M] ;
int sum[N][M] ;
char s[N] ;
int n ;
bool check(int x) {
for (int i = 1; i <= 26; i++) b[i] = iinf ;
for (int r = x; r <= n; r++) {
int l = r - x + 1 ;
for (int i = 1; i <= 26; i++) a[i] = sum[r][i] - sum[l - 1][i] ;
for (int i = 1; i <= 26; i++) b[i] = min(b[i], a[i]) ;
}
for (int i = 1; i <= 26; i++) if (b[i]) return true ;
return false ;
}
signed main(){
scanf("%s", s + 1) ; n = strlen(s + 1) ;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 26; j++) sum[i][j] = sum[i - 1][j] ;
sum[i][s[i] - 'a' + 1]++ ;
}
int l = 0, r = n + 1 ;
while (l + 1 < r) {
int mid = (l + r) >> 1 ;
if (check(mid)) r = mid ;
else l = mid ;
}
printf("%d\n", r) ;
return 0 ;
}