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表示向右 ...
随机推荐
- 【转】C语言正确使用extern关键字
利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int f ...
- 带你玩转Visual Studio——带你理解微软的预编译头技术
原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...
- 007_linux显示一个文件的某几行(中间几行)
<1>从第3000行开始,显示1000行.即显示3000~3999行 cat -n filename | tail -n +3000 | head -n 1000 cat -n anaco ...
- 13-JS中的面向对象
创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 JS中最基本创建对象的 ...
- spring mvc 校验@NULL
一需要的包 1 validation-api-1.0.0.GA.jar:JDK的接口: 2 hibernate-validator-4.2.0.Final.jar 是对上述接口的实现: 二 若在pom ...
- STM32学习及应用笔记二:一次运算符优先级造成的错误
本人在最近一个项目的开发中,出现一个应为疏忽运算符优先级造成的问题,检查了很久才发现问题,所以觉得运算符的优先级问题还是有必要再研究一下.具体的问题是这样的,我采集了传感器的原始数据,然后会对数据进行 ...
- iOS中按钮点击事件处理方式
写在前面 在iOS开发中,时常会用到按钮,通过按钮的点击来完成界面的跳转等功能.按钮事件的实现方式有多种,其中 较为常用的是目标-动作对模式.但这种方式使得view与controller之间的耦合程度 ...
- <a>标签缺少href 属性,鼠标经过不会出现手型
声明: web小白的笔记,欢迎大神指点.联系QQ:1522025433. 直接看实例吧! <!doctype html> <html> <head> <met ...
- linux - awk 和kill 批量杀死进程
ps -ef|grep check_os.sh | grep -v grep | awk '{print $2}' | xargs kill -9 $2表示第2列,即进程号PID; grep -v g ...
- java使用md5加密
代码: public String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingExcep ...