给两个集合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 双旋转字符串的更多相关文章

  1. [bzoj4084][Sdoi2015]双旋转字符串_hash

    双旋转字符串 bzoj-4084 Sdoi-2015 题目大意:给定两个字符串集合 S 和 T .其中 S 中的所有字符串长度都恰好为 N ,而 T 中所有字符串长度都恰好为 M .且 N+M 恰好为 ...

  2. BZOJ 4084 [Sdoi2015]双旋转字符串

    题解:hash 至今不会unsigned long long 的输出 把B扔进map 找A[mid+1][lenA]在A[1][mid]中的位置 把A[1][mid]贴两遍(套路) 枚举A[mid+1 ...

  3. 【bzoj4084】【sdoi2015】双旋转字符串

    题解 首先题中说了$n>=m$; 分成的循环串左右两边为本质相同的单循环串循环串,分别长为$l = \frac{n + m}{2} $; 所以$S$串的前$l$位为双循环串的一半$S1$,后一半 ...

  4. 剑指Offer面试题:34.翻转单词顺序VS左旋转字符串

    一.题目一:翻转单词顺序 1.1 题目说明 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...

  5. 【面试题042】翻转单词顺序VS左旋转字符串

    [面试题042]翻转单词顺序VS左旋转字符串 题目一:     输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.     例如输入字符串“I a ...

  6. lintcode :旋转字符串

    题目: 旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdef ...

  7. 九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1362 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运 ...

  8. LintCode 面试题 旋转字符串

    1.题目描述 题目链接:http://www.lintcode.com/zh-cn/problem/rotate-string/ 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 2. ...

  9. 1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏

    1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右 ...

随机推荐

  1. python内存数据库pydblite

    Pure-Python engine 最近由于项目开发中发现python informixDB模块对多线程的支持非常不好,当开启两个线程同时连接informix数据库的时候,数据库会报错,显示SQL ...

  2. 转载:Java中的字符串常量池详细介绍

    引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...

  3. Ex 5_21 无向图G=(V,E)的反馈边集..._第九次作业

    根据题意,求的是最大生成树.利用Kruskal算法,对边进行从大到小的顺序进行排序,然后再依次取出边加入结果集中.假设图有n个顶点,那么,当结果集中有n-1条边时,剩下的边的集合即为反馈边集. pac ...

  4. table下tbody滚动条与thead对齐的方法且每一列可以不均等

    1 前言 table下tbody滚动条与thead对齐的方法,开始在tbody的td和thead的tr>td,对每一个Item加入百分比,结果是没对齐.也尝试了用bootstrap的col-md ...

  5. MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)

    农历 乙未 羊年 十一月初九 周六 2015年12月19日 14:29 编辑者:刘军 标题: 服务器的搭建请参考该文:<Win7 x64 svn 服务器搭建> ============== ...

  6. python 全栈开发,Day98(路飞学城背景,django ContentType组件,表结构讲解)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  7. centos下配置DNS

    centos网络配置实例 1,配置DNSvi /etc/resolv.conf加入: 代码如下: nameserver 192.168.0.1 nameserver 8.8.8.8 nameserve ...

  8. 《剑指offer》-双栈实现队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 很基本的STL容器操作了,应该可以1A的,但是忘记返回值的时候,clang的报错感觉并不友好啊.. cl ...

  9. HDU 3980 (SG 环变成链 之前的先手变成后手)

    题意 两个人在一个由 n 个玻璃珠组成的一个圆环上玩涂色游戏,游戏的规则是: 1.每人一轮,每轮选择一个长度为 m 的连续的.没有涂过色的玻璃珠串涂色 2.不能涂色的那个人输掉游戏 Aekdycoin ...

  10. ahoi2009维护序列

    链接:https://www.luogu.org/problemnew/show/P2023 裸的线段树维护+* 代码: #include <bits/stdc++.h> using na ...