C. K-Complete Word(小小的并查集啦~)

永久打开的传送门

\(\color{Pink}{-------------分割-------------}\)

\(n最大有2e5,那么暴力一定不行,找规律\)

\(我们发现第i位的字符一定和第i+k位相等(周期)\)

\(第i位的字符一定和第n-i+1位字符相等(回文)\)

\(那么每次把i,i+k,n-i+1合并到一个集合(并查集)\)

\(最后一定是分成了若干个集合,集合中的元素要相等\)

\(那我们再统计每个集合的元素个数和集合里出现字符最多的字母\)

\(于是我们规定这个集合都变成出现次数最多的那个字母,就好啦\)~~~

\(最后是233ms,还不算太慢吧......\)

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+9;
int pre[maxn],n,k,t,vis[maxn][26];
char s[maxn];
int find(int x){
    return x==pre[x]?pre[x]:pre[x]=find(pre[x]);
}
void join(int q,int w){
    pre[find(q)]=find(w);
}
inline int max(int a,int b){return a>b?a:b;}
int main()
{
    cin>>t;
    while(t--)
    {
        int ans=0;  
        cin>>n>>k>>(s+1);
        for(int i=0;i<=n;i++)    pre[i]=i;   
        for(int i=1;i<=n/2;i++)
        {
            if(i+k<=n)   join(i,i+k);
            join(i,n-i+1);
        }
        for(int i=1;i<=n;i++)
        {
            int num=s[i]-'a';
            vis[find(i)][num]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(pre[i]!=i)   continue;
            int he=0,maxx=0;
            for(int j=0;j<=25;j++)
            {
                he+=vis[i][j];
                maxx=max(maxx,vis[i][j]);
                vis[i][j]=0;//清空为下次做准备 
            }
            ans+=(he-maxx);
        }
        cout<<ans<<endl;
    }
}

原文链接: https://www.cnblogs.com/iss-ue/p/12848816.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C. K-Complete Word(小小的并查集啦~)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/347205

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午4:23
下一篇 2023年3月2日 上午4:23

相关推荐