zoukankan      html  css  js  c++  java
  • Just A String(KMP)

    Just A String(KMP)

    题意:给一个字符串,枚举所有前缀与后缀,计 前缀 的后缀与 后缀 的前缀的最长公共部分为B,前缀剩余部分为A,后缀剩余部分为C(A,B,C表示长度),求所有前后缀的A * B * B * C,输出其异或和。(字符串长2000)

    翻车体会:要求前缀的后缀,与后缀的前缀。想到用KMP处理后缀,因为后缀要求的是前缀,可用KMP快速解决前缀问题,然后查前缀的后缀,利用后缀跑KMP前缀必然匹配不到,我的想法是将原串复制接在后面,这样就能匹配到了(其实只要将原串作为匹配串再跑一遍KMP就行了),枚举所有后缀计算出每个后缀的KMP,然后计算每一个前缀的答案,这边我连接的时候并没有细节的再中间加一个#,出现了最长公共部分大于两个原串的情况,然后直接与原串大小取min,前缀匹配后缀计算出来的最长公共部分是无单调性的,导致wa。所以这题直接与原串匹配就好了。

    #include<iostream>
    #include<cstring>
    using namespace std;
    #define ll long long
    ll t,n,nex[5007];
    string s,s2;
    void kmp(string s){
    	ll len=s.length();
    	ll l=0,r=1;
    	nex[l]=-1;
    	while(r<len){
    		if(l==-1||s[l]==s[r]){
    			l++;
    			r++;
    			nex[r]=l;
    		}
    		else l=nex[l];
    	}
    }
    int main(){
    	scanf("%lld",&t);
    	while(t--){
    		cin>>s;
    		n=s.length();
    		s+=s;
    		ll ans=0;
    		for(ll j=1;j<=n;j++){
    			s2="";
    			for(ll i=n-j;i<n;i++){
    				s2+=s[i];
    			}
    			kmp(s2);
    			ll l=0,r=0;
    			while(r<n){
    				if(l==-1||s2[l]==s[r]){
    					l++;
    					r++;
    					ans^=(r-l)*l*l*(j-l);
    					while(l==s2.length())l=nex[l];
    				}
    				else l=nex[l];
    			}
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
    
  • 相关阅读:
    Chromium(Chrome) frame structure detail
    Chromium(Chrome) Sandbox Details
    ECMA6 New Features
    Asynchronous programming in javascript
    Restful OData Protocol
    java 历年版本特征(简化)
    λ 演算学习
    远程访问其他主机的Mysql(Ubuntu)
    NoSQL基础学习
    Apache solr 6.6.0安装
  • 原文地址:https://www.cnblogs.com/whitelily/p/13750184.html
Copyright © 2011-2022 走看看