2017 ACM-ICPC西安赛区网络赛 Barty's Computer【哈希】
来源:互联网 发布:名校毕业生知乎 编辑:程序博客网 时间:2024/06/05 08:48
题目:https://nanti.jisuanke.com/t/17122
题意:一共Q次操作,操作有两种:
1 str : 表示增加一个字符串str(长度一定是偶数)
2 a b c d : 询问有多少个字符串满足str = a + s1 + b + c + s2 + d, 且|a|+|s1|+|b| = |c|+|s2|+|d|, s1, s2可以是任意字符串,空的也可以。
Q <= 3e4, ∑∣s∣+∣a∣+∣b∣+∣c∣+∣d∣≤2000000.
思路:因为要求|a|+|s1|+|b| = |c|+|s2|+|d|, 所以我们可以知道|a|+|s1|+|b| 和 |c|+|s2|+|d|分别为某个字符串的前一半和后一半。所以我们现在只要找到字符串满足前一半的前缀是a, 后缀是b, 后一半的前缀是c, 后缀是d即可。怎么快速判断一个串的前缀或后缀是否是某一个字符串呢?我们可以用hash, 这样就能以O(1)复杂度判断某个串是否满足,所以每次询问枚举所有串即可。
判断一个字符串是否为另一个串的前缀或后缀我们也可以用字典树来做,logn复杂度。
这题的具体操作是建立四颗字典树,分别为每个串的前一半的正序,前一半的逆序,后一半的正序,后一半的逆序建立的。这样每次询问,每次abcd四个字符串分别取对应的字典树找即可,四棵树找到的交集的个数就是答案,(字典树每个节点都应该是个vector)
参考:http://blog.csdn.net/cillyb/article/details/78156360
#include <iostream>#include <algorithm>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <cstdio>#include <cstring>#include <cmath>using namespace std;typedef long long LL;const int N=3e4+9;const int mod=1e9+7;const int seed=233;const int M=2e6+9;typedef pair<int,int> pii;char s[M],a[M],b[M],c[M],d[M];LL Hash[M],fac[M]={1};int Len[N],num[N];int main(){ for(int i=1;i<M;i++) fac[i]=fac[i-1]*seed%mod; int T;scanf("%d",&T); while(T--){ int cnt=0,Q,op,idx=0; scanf("%d",&Q); while(Q--){ scanf("%d",&op); if(op==1){ scanf("%s",s); int len=strlen(s); Len[cnt]=len; num[cnt]=idx; for(int i=idx;i < idx+len;i++){ if(i==idx)Hash[i]=s[i-idx]-'a'; else Hash[i]=(Hash[i-1]*seed+s[i-idx]-'a')%mod; } idx+=len; cnt++; } else{ scanf("%s%s%s%s",a,b,c,d); int lena=strlen(a); int lenb=strlen(b); int lenc=strlen(c); int lend=strlen(d); LL hasha=0,hashb=0,hashc=0,hashd=0; for(int i=0;i<lena;i++)hasha=(hasha*seed+a[i]-'a')%mod; for(int i=0;i<lenb;i++)hashb=(hashb*seed+b[i]-'a')%mod; for(int i=0;i<lenc;i++)hashc=(hashc*seed+c[i]-'a')%mod; for(int i=0;i<lend;i++)hashd=(hashd*seed+d[i]-'a')%mod; int ans=0; for(int i=0;i<cnt;i++){ if(lena+lenb>Len[i]/2||lenc+lend>Len[i]/2)continue; LL *has =Hash+num[i]-1; LL mid=Len[i]/2; LL tmp=has[lena]; if(tmp!=hasha)continue; tmp = (has[mid]-has[mid-lenb]*fac[lenb]%mod+mod)%mod; if(tmp!=hashb)continue; tmp = (has[mid+lenc]-has[mid]*fac[lenc]%mod+mod)%mod; if(tmp!=hashc)continue; tmp= (has[Len[i]]-has[Len[i]-lend]*fac[lend]%mod+mod)%mod; if(tmp!=hashd)continue; ans++; } printf("%d\n",ans); } } } return 0;}
阅读全文
0 0
- 2017 ACM-ICPC西安赛区网络赛 Barty's Computer【哈希】
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Barty's Computer(暴力+hash)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 I. Barty's Computer(哈希||字典树)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛
- 2017ACM-ICPC西安赛区
- 2017西安邀请赛: I. Barty's Computer(暴力+Hash)
- 2014 ACM/ICPC 西安赛区网络赛解题报告汇总
- 2017 ACM-ICPC 亚洲区(西安赛区)网络...
- 2014ACM-ICPC西安赛区网络预赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin (概率公式+快速幂)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛b题Coin(矩阵快速幂)
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B. Coin
- leetcode 148 sortlist
- python+opencv识别动态物体
- 【密码学】CSP的概念
- JAVA SE — Day 02
- 机器学习常见算法个人总结(面试用)
- 2017 ACM-ICPC西安赛区网络赛 Barty's Computer【哈希】
- 转载:公钥、私钥、USBKey、CSP、数字证书和CryptoAPI的简介
- Win10 成功安装VC++6.0企业版及SP6补丁包
- UML设计中的箭头详解
- 字符串补字符工具类
- Lua学习笔记2-数据类型
- js验证开始时间和结束时间 结束时间不能比开始时间早
- iview框架中文本类型的数据导出excel后以科学记数法显示的解决办法
- 在服务器上安装swoole