CodeForces 1367E Necklace Assembly

題意node

給定一個字符串\(s\),長度爲\(n\),一根項鍊爲一個環,定義一根項鍊爲\(k-beautiful\),則該項鍊順時針轉\(k\)下後與原項鍊相等,給出\(k\),請構造一根最長的\(k-beautiful\)項鍊,項鍊由\(s\)中的一些字符組成,長度爲\(1\)的項鍊和組成字符所有相等的項鍊知足任意\(k\)ios

首先最小的答案是最大的字符個數,而後考慮項鍊中字符不全相等的狀況,一根項鍊轉\(k\)下不變,則\(k\)的某個因子可能也知足,不妨設爲\(j\),則\(j-beautiful\)的項鍊也知足\(k-beautiful\),咱們枚舉因子\(j\),而後找到能夠構造出的最長項鍊,設項鍊爲字符串\(t\),注意到\(j-beautiful\)的項鍊有\(t[1]=t[j+1],\cdots ,t[j-1]=t[2*j-1]\),注意到這個等式能夠繼續下去,那麼咱們要考慮項鍊的節數,每節有\(j\)個字符,那麼要找到能夠知足的最大節數,最長的\(j-beautiful\)項鍊即爲:最大節數乘以\(j\),這個最大節數具備二分性質,二分便可c++

#pragma GCC optimize(3, "Ofast", "inline")
 
#include <bits/stdc++.h>
 
#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
#define rep(z, x, y) for(int z=x;z<=y;++z)
#define com bool operator<(const node &b)
using namespace std;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const int maxn = (ll) 5e6 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
int T = 1;
int num[26];
 
bool check(int each, int jie) {
    rep(i, 0, 25) {
        each -= num[i] / jie;
        if (each <= 0)
            return true;
    }
    return false;
}
 
void solve() {
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    int ans = 1;
    rep(i, 0, 25)num[i] = 0;
    rep(i, 0, s.size() - 1)++num[s[i] - 'a'], ans = max(ans, num[s[i] - 'a']);
    vector<int> v;
    for (int i = 2; i <= k; ++i) {
        if (k % i == 0)
            v.push_back(i);
    }
    for (auto &each:v) {
        int l = 1, r = n / each;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (check(each, mid))
                ans = max(ans, mid * each), l = mid + 1;
            else
                r = mid - 1;
        }
    }
    cout << ans << '\n';
}
 
signed main() {
    start;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
相關文章
相關標籤/搜索