标签:2000005 字符 朋友 int 三个 ull 字符串 两段
题目描述
给出一个字符串U,求满足条件的字符串S使其复制一遍再插入一个字符后的字符串为U。
思路
由于插入过一个字符,所以我们可以进行一次扫描,每次扫描时将这个字符去掉,把去掉后字符串分成长度相等的两段,再比较这两段是否完全相同即可。如果暴力枚举看是否相同肯定会T飞,我们考虑使用字符串Hash,求出两段的Hash值比较是否相等即可。需要注意的有两点:①把字符串取出时注意对进制转换;②有可能会存在多个相等的S,它们不算重复。
代码
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; const ull p=47; char s[2000005]; ull sum[2000005],power[2000005]; int main() { // freopen("aa.txt","r",stdin); int n; scanf("%d",&n); scanf(" %s",s+1); if(n%2==0){printf("NOT POSSIBLE");return 0;} int len=(n-1)/2; power[0]=1; for(int i=1;i<=n;i++) { sum[i]=sum[i-1]*p+s[i]-'A'; power[i]=power[i-1]*p; } ull ans=0,k=0,l=0; bool f=1; // cout<<sum[4]<<endl; for(int i=1;i<=n;i++) { if(i<=len+1) { ull s1=sum[i-1]*power[len-i+1]+(sum[len+1]-sum[i]*power[len-i+1]); ull s2=sum[n]-sum[n-len]*power[len]; if(s1==s2) { ans++; if(ans==1)k=s1,l=i; else if(k!=s1)f=0; } // cout<<i<<' '<<s1<<' '<<s2<<' '<<ans<<endl; } else { ull s1=sum[len]; ull s2=(sum[i-1]-sum[len]*power[i-len-1])*power[len*2-i+1]+sum[n]-sum[i]*power[n-i]; if(s1==s2) { ans++; if(ans==1)k=s1,l=i; else if(k!=s1)f=0; } // cout<<i<<' '<<s1<<' '<<s2<<' '<<ans<<endl; } } // cout<<ans<<' '<<l<<endl; if(ans==1||(ans>1&&f)) { if(l<=len+1) for(int i=n-len+1;i<=n;i++) putchar(s[i]); else for(int i=1;i<=len;i++) putchar(s[i]); } else if(ans==0) printf("NOT POSSIBLE"); else printf("NOT UNIQUE"); return 0; }
标签:2000005,字符,朋友,int,三个,ull,字符串,两段 来源: https://www.cnblogs.com/fangbozhen/p/11619392.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。