zoukankan      html  css  js  c++  java
  • P7114 [NOIP2020] 字符串匹配 题解

    问题描述

    。。。我不太想说 NOIP2020噩梦

    P7114 [NOIP2020] 字符串匹配

    问题解决

    君子报仇,十年不晚

    这道题考场上写了一个(O(nlognlog26))的解法,不够优秀被卡掉了

    后面看了题解,然后写了一个(O(nlog26))的解法

    引入拓展(kmp)中的(z)函数:(z[i])表示(s[i,n-1])(s)本身的最长公共前缀的长度

    先不考虑奇数,对于循环节为(i)的字符串,可以计算上的就是(leftlfloordfrac{z[i]}{i} ight floor +1)

    然后对于 (k) 分奇偶讨论,我们发现奇数和偶数满足的条件是相同的,于是乘法原理加上树状数组统计一下就好了

    代码实现

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=(1<<20)+5;
    char s[maxn];
    int n,z[maxn],before[30],after[30],pre,suf,all;
    int c[30],T;
    inline void add_x(int x,int data){
    	for(int i=x;i<=27;i+=i&-i)c[i]+=data;
    }
    inline int get(int x){
    	int ret=0;
    	for(int i=x;i;i-=i&-i)ret+=c[i];
    	return ret;
    }
    void Z(){
    	z[0]=n; int now=0;
    	while(now+1<n&&s[now]==s[now+1])now++;
    	z[1]=now;int p0=1;
    	for(int i=2;i<n;i++){
    		if(i+z[i-p0]<p0+z[p0]) z[i]=z[i-p0];
    		else {
    			now=p0+z[p0]-i;now=max(now,0);
    			while(now+i<n&&s[now]==s[now+i])now++;
    			z[i]=now;p0=i;
    		}
    	}
    }
    
    int main(){
    	freopen("P7114.in","r",stdin);
    	freopen("P7114.out","w",stdout);
    	scanf("%d",&T);
    	while(T--){
    		scanf("%s",s);
    		n=strlen(s);
    		memset(before,0,sizeof before);
    		memset(after,0,sizeof after);
    		memset(c,0,sizeof c);
    		all=pre=suf=0;Z();
    		for(int i=0;i<n;i++) i+z[i]==n&&(z[i]--,0);
    		for(int i=0;i<n;i++) after[s[i]-'a']++;
    		for(int i=0;i<26;i++) (after[i]&1)&&(all++,0);
    		suf=all;LL ans=0;
    		for(int i=0;i<n;i++){
    			if(after[s[i]-'a']&1)suf--;else suf++;after[s[i]-'a']--;
    			if(before[s[i]-'a']&1)pre--;else pre++;before[s[i]-'a']++;
    			if(i!=0&&i!=n-1){
    				int t=z[i+1]/(i+1)+1;
    				ans+=1LL*(t/2)*get(all+1)+1LL*(t-t/2)*get(suf+1);
    			}
    			add_x(pre+1,1);
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    nginx 反向代理 apache 服务
    IIS 设置404页面 显示系统找不到指定的文件
    centos6.6 下 安装 nginx
    sql优化建议
    php的静态化
    vsftp上传文件出现553 Could not create file
    php安装libevent扩展
    discuz回贴通知插件实现-显示用户状态设置
    discuz回贴通知插件实现-插件的多语言
    discuz回贴通知插件实现-插件后台管理配置
  • 原文地址:https://www.cnblogs.com/martian148/p/15340067.html
Copyright © 2011-2022 走看看