链接:https://ac.nowcoder.com/acm/contest/3/J

来源:牛客网

Just A String

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 262144K,其他语言524288K

64bit IO Format: %lld

题目描述

何老师手中有一个字符串S,他发现这个字符串有一个神奇的性质,取出一个长为i的前缀(就是由S的前i个字符顺序构成的字符串)prei和一个长为j的后缀(就是由S的后j个字符顺序构成的字符串)sufj之后,总是存在三个字符串A,B,C(可能为空)使得prei=A+B,sufj=B+C, 虽然这听起来像是一句废话。

显然三元组A,B,C不总是唯一的,何老师从所有可能的三元组中找到B最长的,很容易知道这样的三元组是唯一的,并且认为prei和sufj的契合度就是f(i,j)=|A||B|2|C|,现在你需要帮何老师算出所有f(i,j)(0 ≤ i,j ≤ n)的异或和。

这里|X|表示字符串X的长度,X+Y表示将两个字符串X和Y顺序拼接起来后得到的新字符串。

输入描述:

第一行是一个正整数T(≤ 500),表示测试数据的组数, 每组测试数据,包含一个仅由小写字母构成的非空字符串S(|S| ≤ 2000), 保证满足|S|>200的数据不超过5组。

输出描述:

对于每组测试数据,输出所有f(i,j)(0 ≤ i,j ≤ n)的异或和。

示例1

输入

复制

1

abcab

输出

复制

13

题意:



思路:

纯暴力的算法显然是nnn 的时间复杂度,稳稳的TLE,

我们可以通过利用kmp算法来优化一个n,使其是n*n 的时间复杂度。

我们通过枚举给定字符串str的后缀temp字符串,然后构建next数组与整个字符串str进行匹配,我们知道这个kmp的匹配过程用两个下标变量进行滑动,

  1. if(str1[x]==str2[y])
  2. {
  3. // 只需要加这三行
  4. int len=y+1;
  5. ll a=x+1-len;ll b=len;ll c=m-len;
  6. // cout<<a<<" "<<b<<" "<<c<<" "<<ans<<" "<<a*b*b*c<<endl;
  7. ans^=(a*b*b*c);
  8. // db(ans);
  9. x++;
  10. y++;
  11. }

里面遇到两个字符相等的时候,我们是让其下标都+1,而我们可以在+1之前计算出以当前后缀字符串与x+1长度前缀字符串对答案的贡献值,这里主要通过next数组对 题意中要求的B数值进行的优化,因为想让一个情况对答案有贡献,前提是a,b,c 均不为0,不然一个数异或0没有影响,。那么B不为0的情况就可以在kmp匹配过程中所有str1[x]==str2[y] 情况中计算。代码中有细节注释

细节见代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <queue>
  7. #include <stack>
  8. #include <map>
  9. #include <set>
  10. #include <vector>
  11. #include <iomanip>
  12. #define ALL(x) (x).begin(), (x).end()
  13. #define rt return
  14. #define sz(a) int(a.size())
  15. #define all(a) a.begin(), a.end()
  16. #define rep(i,x,n) for(int i=x;i<n;i++)
  17. #define repd(i,x,n) for(int i=x;i<=n;i++)
  18. #define pii pair<int,int>
  19. #define pll pair<long long ,long long>
  20. #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
  21. #define MS0(X) memset((X), 0, sizeof((X)))
  22. #define MSC0(X) memset((X), '\0', sizeof((X)))
  23. #define pb push_back
  24. #define mp make_pair
  25. #define fi first
  26. #define se second
  27. #define eps 1e-6
  28. #define gg(x) getInt(&x)
  29. #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
  30. using namespace std;
  31. typedef long long ll;
  32. ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
  33. ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
  34. ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
  35. inline void getInt(int* p);
  36. const int maxn=1000010;
  37. const int inf=0x3f3f3f3f;
  38. /*** TEMPLATE CODE * * STARTS HERE ***/
  39. string str;
  40. int Next[5000];
  41. void getnext(string str)
  42. {
  43. int len=str.length();
  44. Next[0]=-1;
  45. int i=0;
  46. int j=-1;
  47. while(i<len)
  48. {
  49. if(j==-1||str[i]==str[j])
  50. {
  51. i++;j++;
  52. Next[i]=j;
  53. }else
  54. {
  55. j=Next[j];
  56. }
  57. }
  58. }
  59. ll ans=0ll;
  60. int kmp(string str1,string str2,int k)// 从k下标开始查找
  61. {
  62. int x,y;
  63. y=0;
  64. x=k;
  65. int n,m;
  66. n=str1.length();
  67. m=str2.length();
  68. getnext(str2);// 获得next数组
  69. while(x<n&&y<m)
  70. {
  71. if(str1[x]==str2[y])
  72. {
  73. // 只需要加这三行
  74. int len=y+1;
  75. ll a=x+1-len;ll b=len;ll c=m-len;
  76. // cout<<a<<" "<<b<<" "<<c<<" "<<ans<<" "<<a*b*b*c<<endl;
  77. ans^=(a*b*b*c);
  78. // db(ans);
  79. x++;
  80. y++;
  81. }else if(y==0)
  82. {
  83. x++;
  84. }else
  85. {
  86. y=Next[y];
  87. }
  88. if(y==m)
  89. {
  90. y=Next[y]; // 如果不考虑重叠的,这里置零
  91. // return x+1-str2.length();// 返回第一个匹配成功的起始位置
  92. }
  93. }
  94. return 0;
  95. }
  96. int main()
  97. {
  98. // freopen("D:\\code\\text\\input.txt","r",stdin);
  99. //freopen("D:\\code\\text\\output.txt","w",stdout);
  100. int t;
  101. cin>>t;
  102. while(t--)
  103. {
  104. ans=0ll;
  105. cin>>str;
  106. int n=str.length();
  107. for(int i=0;i<n;i++)
  108. {
  109. string temp=str.substr(i);// 获得str从i开始到结束的后缀字符串
  110. kmp(str,temp,0);
  111. }
  112. cout<<ans<<endl;
  113. }
  114. return 0;
  115. }
  116. inline void getInt(int* p) {
  117. char ch;
  118. do {
  119. ch = getchar();
  120. } while (ch == ' ' || ch == '\n');
  121. if (ch == '-') {
  122. *p = -(getchar() - '0');
  123. while ((ch = getchar()) >= '0' && ch <= '9') {
  124. *p = *p * 10 - ch + '0';
  125. }
  126. }
  127. else {
  128. *p = ch - '0';
  129. while ((ch = getchar()) >= '0' && ch <= '9') {
  130. *p = *p * 10 + ch - '0';
  131. }
  132. }
  133. }

北京师范大学第十五届ACM决赛-重现赛J Just A String (kmp算法延伸)的更多相关文章

  1. 北京师范大学第十五届ACM决赛-重现赛

    Another Server 时间限制:1秒 空间限制:262144K 题目描述 何老师某天在机房里搞事情的时候,发现机房里有n台服务器,从1到n标号,同时有2n-2条网线,从1到2n-2标号,其中第 ...

  2. 北京师范大学第十五届ACM决赛-重现赛K Keep In Line ( 字符串模拟实现)

    链接:https://ac.nowcoder.com/acm/contest/3/K 来源:牛客网 Keep In Line 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...

  3. 北京师范大学第十五届ACM决赛-重现赛 B Borrow Classroom (树 ——LCA )

    链接:https://ac.nowcoder.com/acm/contest/3/B 来源:牛客网 Borrow Classroom 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 2 ...

  4. 北京师范大学第十五届ACM决赛-重现赛D Disdain Chain (规律+组合数学)

    链接:https://ac.nowcoder.com/acm/contest/3/D 来源:牛客网 Disdain Chain 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

  5. 北京师范大学第十五届ACM决赛-重现赛E Euclidean Geometry (几何)

    链接:https://ac.nowcoder.com/acm/contest/3/E 来源:牛客网 Euclidean Geometry 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ ...

  6. 北京师范大学第十五届ACM决赛-重现赛C Captcha Cracker (字符串模拟)

    链接:https://ac.nowcoder.com/acm/contest/3/C 来源:牛客网 Captcha Cracker 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26 ...

  7. 北京师范大学第十四届ACM决赛-重现赛 F:Training Plan(DP)

    传送门 题意 将n个数分成m个集合,\(V_i表示max(x-y),x,y∈第\)i个集合,\(求minΣV_i\) 分析 我们先对难度排序,令dp[i][j]表示前i个数分成j个集合的最小费用 转移 ...

  8. 北京师范大学第十六届程序设计竞赛决赛-重现赛-B题

    一.题目链接 https://www.nowcoder.com/acm/contest/117/B 二.题意 给定一组序列$a_1,a_2,\cdots,a_n$,表示初始序列$b_1,b_2,\cd ...

  9. 北京师范大学第十六届程序设计竞赛决赛 F 汤圆防漏理论

    链接:https://www.nowcoder.com/acm/contest/117/F来源:牛客网 汤圆防漏理论 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他 ...

随机推荐

  1. 初识REST

    RESTful介绍: REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”. 1 ...

  2. Vue 中 双向绑定数据

    1.文本 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  3. route Cmd详解

    第一条命令,配置外网网关: route -p add 0.0.0.0 mask 0.0.0.0 192.168.1.1 第二条命令,配置内网网关:route -p add 192.168.0.0 ma ...

  4. javascript注

    1.浮点数: e表示法(科学计数法-10的指数次幂): let floatNum = 3.12e2; //等于312 浮点数的最高精度是17位小数. 浮点数计算精度远不如整数,0.15加0.15的和是 ...

  5. Ubuntu 12.04输入密码登陆后又跳回到登录界面

    先找到这个文件: /home/user/.xsession-errors 打开这个文件.   这个文件记录了系统启动的日志,从这里你就可以看到启动的时候哪里出了问题. 对于我的来说,问题出在这里: & ...

  6. tensorflow学习——调试ctc的两个bug

    InvalidArgumentError (see above for traceback): Not enough time for target transition sequence (requ ...

  7. 1450:【例 3】Knight Moves

    1450:[例 3]Knight Moves  题解 这道题可以用双向宽度搜索优化(总介绍在  BFS ) 给定了起始状态和结束状态,求最少步数,显然是用BFS,为了节省时间,选择双向BFS. 双向B ...

  8. is_selected()检查是否选中该元素

    is_selected()检查是否选中该元素,一般针对单选框,复选框,返回的结果是bool 值, 以百度登录页面为案例,来验证"下次自动登录"是否勾选,默认是勾选的,返回的结 果应 ...

  9. Django聚合数据

    背景: 有些时候,光靠数据库中已有字段的数据,还不足以满足一些特殊场景的需求,例如显示一个作者的所有书籍数量. 这时候就需要在已有数据基础上,聚合出这些没有的数据. 为查询集生产聚合: Django ...

  10. 【ABAP系列】SAP ABAP控制单元格是否可编辑

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP控制单元格是否可 ...