bzoj 4084 双旋转字符串
给两个集合A,B,找满足要求的(a,b)的对数,可以计算对于a,哪些b成立.
还有就是字符串hash的使用,感觉平时用字符串hash太少了.
- /**************************************************************
- Problem: 4084
- User: idy002
- Language: C++
- Result: Accepted
- Time:6456 ms
- Memory:290272 kb
- ****************************************************************/
- #include <cstdio>
- #include <set>
- #include <vector>
- #include <algorithm>
- #define N 8000010
- #define Base 31
- #define Mod 1000000007
- using namespace std;
- typedef long long dnt;
- int n, m, ln, lm;
- char *sa[N], *sb[N];
- char buf_arr[N], *buf=buf_arr;
- dnt fx[N], sx[N], pow[N];
- int fail[N];
- multiset<int> stb;
- int hash( char *s ) {
- dnt rt = ;
- for( int i=; s[i]; i++ )
- rt = (rt*Base + s[i]-'a') % Mod;
- return rt;
- }
- void init_hash( int ln, char *s ) { // ln>=1
- fx[] = s[]-'a';
- for( int j=; j<ln; j++ )
- fx[j] = (fx[j-]*Base + s[j]-'a') % Mod;
- sx[ln-] = s[ln-]-'a';
- for( int j=ln-; j>=; j-- )
- sx[j] = ((s[j]-'a')*pow[ln--j] + sx[j+]) % Mod;
- }
- void init_fail( char *s ) {
- fail[] = ;
- fail[] = ;
- for( int i=; s[i]; i++ ) {
- int j=fail[i];
- while( j && s[j]!=s[i] ) j=fail[j];
- if( s[j]==s[i] )
- fail[i+]=j+;
- else
- fail[i+]=;
- }
- }
- void work1() { // ln > lm
- vector<int> vc;
- int ll = (ln+lm)>>;
- dnt ans = ;
- for( int t=; t<=n; t++ ) {
- init_fail(sa[t]+ll);
- for( int i=; i<ll; i++ )
- buf[i] = sa[t][i];
- for( int i=; i<ll; i++ )
- buf[ll+i] = sa[t][i];
- init_hash(ll+ll,buf);
- vc.clear();
- int i=, j=;
- while( i<ln- ) {
- while( i<ln- && j<ln-ll && buf[i]==sa[t][ll+j] ) i++, j++;
- if( j==ln-ll ) {
- dnt v;
- v = fx[i+(ll+ll-ln)-]-fx[i-]*pow[ll+ll-ln];
- v = (v%Mod+Mod) % Mod;
- vc.push_back(v);
- j = fail[ln-ll];
- }
- if( i==ln- ) break;
- while( j && sa[t][ll+j]!=buf[i] ) j=fail[j];
- if( sa[t][ll+j]!=buf[i] ) i++;
- }
- sort( vc.begin(), vc.end() );
- vc.erase( unique(vc.begin(),vc.end()), vc.end() );
- for( int t=; t<vc.size(); t++ )
- ans += stb.count(vc[t]);
- }
- printf( "%lld\n", ans );
- }
- void work3() { // ln = lm
- vector<int> vc;
- dnt ans = ;
- for( int i=; i<=n; i++ ) {
- init_hash(ln,sa[i]);
- vc.clear();
- vc.push_back( sx[] );
- for( int j=; j<ln; j++ ) {
- int v = ((dnt)sx[j]*pow[j]+fx[j-]) % Mod;
- vc.push_back(v);
- }
- sort( vc.begin(), vc.end() );
- vc.erase( unique(vc.begin(), vc.end()), vc.end() );
- for( int t=; t<vc.size(); t++ )
- ans += stb.count(vc[t]);
- }
- printf( "%lld\n", ans );
- }
- int main() {
- scanf( "%d%d%d%d", &n, &m, &ln, &lm );
- if( ln>lm ) {
- for( int i=; i<=n; i++ ) {
- scanf( "%s", buf );
- sa[i] = buf;
- buf += ln+;
- }
- for( int i=; i<=m; i++ ) {
- scanf( "%s", buf );
- sb[i] = buf;
- buf += lm+;
- }
- } else {
- swap(n,m);
- swap(ln,lm);
- for( int i=; i<=m; i++ ) {
- scanf( "%s", buf );
- sb[i] = buf;
- reverse( buf, buf+lm );
- buf += lm+;
- }
- for( int i=; i<=n; i++ ) {
- scanf( "%s", buf );
- sa[i] = buf;
- reverse( buf, buf+ln );
- buf += ln+;
- }
- }
- pow[] = ;
- for( int i=; i<=ln; i++ )
- pow[i] = pow[i-]*Base % Mod;
- for( int i=; i<=m; i++ )
- stb.insert( hash(sb[i]) );
- if( ln!=lm )
- work1();
- else
- work3();
- }
bzoj 4084 双旋转字符串的更多相关文章
- [bzoj4084][Sdoi2015]双旋转字符串_hash
双旋转字符串 bzoj-4084 Sdoi-2015 题目大意:给定两个字符串集合 S 和 T .其中 S 中的所有字符串长度都恰好为 N ,而 T 中所有字符串长度都恰好为 M .且 N+M 恰好为 ...
- BZOJ 4084 [Sdoi2015]双旋转字符串
题解:hash 至今不会unsigned long long 的输出 把B扔进map 找A[mid+1][lenA]在A[1][mid]中的位置 把A[1][mid]贴两遍(套路) 枚举A[mid+1 ...
- 【bzoj4084】【sdoi2015】双旋转字符串
题解 首先题中说了$n>=m$; 分成的循环串左右两边为本质相同的单循环串循环串,分别长为$l = \frac{n + m}{2} $; 所以$S$串的前$l$位为双循环串的一半$S1$,后一半 ...
- 剑指Offer面试题:34.翻转单词顺序VS左旋转字符串
一.题目一:翻转单词顺序 1.1 题目说明 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...
- 【面试题042】翻转单词顺序VS左旋转字符串
[面试题042]翻转单词顺序VS左旋转字符串 题目一: 输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理. 例如输入字符串“I a ...
- lintcode :旋转字符串
题目: 旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdef ...
- 九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】
题目地址:http://ac.jobdu.com/problem.php?pid=1362 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运 ...
- LintCode 面试题 旋转字符串
1.题目描述 题目链接:http://www.lintcode.com/zh-cn/problem/rotate-string/ 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 2. ...
- 1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏
1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右 ...
随机推荐
- Mashup
简介 mashup是糅合,是当今网络上新出现的一种网络现象,将两种以上使用公共或者私有数据库的web应用,加在一起,形成一个整合应用.一般使用源应用的API接口,或者是一些rss输出(含atom)作为 ...
- python中对列表和循环使用的小练习
#author devilf product_list = [ (), (), (), (), () ] shop_list = [] salary = input('pls enter your s ...
- 部署vCenter Server Appliance 6.7
=============================================== 2019/4/14_第1次修改 ccb_warlock == ...
- position:absolute在IE8浏览器下无法显示正确位置
在网页head下添加 <meta http-equiv="x-ua-compatible" content="ie=8" />
- OCM_第五天课程:Section2 —》AGENT 的安装 、GC 的使用
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- SSD笔记
参考:https://zhuanlan.zhihu.com/p/24954433?refer=xiaoleimlnote http://blog.csdn.net/u010167269/article ...
- windows10+mysql8.0.11zip安装
准备: MySQL8.0 Windows zip包下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-winx64.zip 环境: ...
- js数值进制互转
十进制转换为二进制: var num = 100; console.log(num.toString(2)); toString()方法可把一个 Number 对象转换为一个字符串,并返回结果. 语法 ...
- MySQL表的定期分析检查优化
Analyze Table 分析表 MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为“散列程度”),它表示 ...
- whiledo循环输出数组中的分数
var scores = [24, 32, 17]; var arrayLength = scores.length; var i =0; while(i < arrayLength){ var ...