补题:Div2 #578 E. Compress Words
时间:2021-07-15
本文章向大家介绍补题:Div2 #578 E. Compress Words,主要包括补题:Div2 #578 E. Compress Words使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
补题:Div2 #578 E. Compress Words
从第一个单词开始,如果前一个单词的后缀和后一个单词的前缀相同,那么把他们合并,求最后合并后的串
每新读入一个新字符串就将其和已有的字符串合并,不是合并i和i-1
想法就是对想合并的两个串求哈希值,然后枚举能合并的前缀后缀的长度
单模数hash在codeforces上很容易被hack的,建议双模数hash
如果时间超限的话,可以考虑预处理快速幂,能少个log
(hash查询是O(1)的,所以在某些情况下可以往稍稍暴力的方面想)
(太久没写被卡细节=_=)
#include<bits/stdc++.h>
using namespace std;
#define PI acos(-1)
#define ll long long
#define clean(a,b) memset(a,b,sizeof(a))
const int inf=0x3f3f3f3f;
const int maxn=1e6+9;
const int mod=1e9+7;
const int mod_=1e9+9;
inline ll read()
{
register ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
string s[maxn];
int base=131;
ll _hash[1000009][6];
int fpo[maxn][3];
ll fpow(ll a,ll b,ll c)
{
a%=c;
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%c;
a=a*a%c;
b>>=1;
}
return ans%c;
}
int get_hash(int l,int r,int x)
{
return (_hash[r+1][x]-_hash[l][x]*fpo[r-l+1][1]%mod+mod)%mod;
}
int get_hash_(int l,int r,int x)
{
return (_hash[r+1][x]-_hash[l][x]*fpo[r-l+1][2]%mod_+mod_)%mod_;
}
int main()
{
#ifdef LOCAL
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
for(int i=1;i<=1e6;i++) fpo[i][1]=fpow(base,i,mod)%mod,fpo[i][2]=fpow(base,i,mod_)%mod_;
int n=read();
cin>>s[1];
int len=s[1].size();
// int now=2;//now
for(int i=0;i<len;i++)
{
_hash[i+1][1]=((_hash[i][1]*base)+s[1][i])%mod;
_hash[i+1][3]=((_hash[i][3]*base)+s[1][i])%mod_;
}
string ans=s[1];
for(int i=2;i<=n;i++)
{
cin>>s[i];
int len=s[i].size();
int anslen=ans.size();
int nowlen=min(len,anslen);
for(int j=0;j<len;j++)
{
_hash[j+1][2]=((_hash[j][2]*base)+s[i][j])%mod;
_hash[j+1][4]=((_hash[j][4]*base)+s[i][j])%mod_;
}
int anss=0;
for(int j=1;j<=nowlen;j++)
{
ll hash_1=get_hash(anslen-j,anslen-1,1);
ll hash_2=get_hash(0,j-1,2);
ll hash_3=get_hash_(anslen-j,anslen-1,3);
ll hash_4=get_hash_(0,j-1,4);
if(hash_1==hash_2) anss=j;
}
for(int j=anss;j<len;j++)
{
int k=j-anss+anslen;
_hash[k+1][1]=((_hash[k][1]*base)+s[i][j])%mod;
_hash[k+1][3]=((_hash[k][3]*base)+s[i][j])%mod_;
ans+=s[i][j];
}
}
cout<<ans;
return 0;
}
/*
12345678
678945646
*/
原文地址:https://www.cnblogs.com/YangKun-/p/15016569.html
- Linux内存(手动释放cache)
- django中间件Middleware
- springboot kafka集成(实现producer和consumer)
- 分布式锁的实现(redis)
- springboot scheduled并发配置
- RabbitMQ高可用集群配置
- zookeeper curator处理会话过期session expired
- redis事务
- 数据库表反向生成(一) MyBatis-generator与IDEA的集成
- 数据库表反向生成(二) Django ORM inspectdb
- RabbitMQ与AMQP协议
- 大数据算法设计模式(2) - 左外链接(leftOuterJoin) spark实现
- hs_err_pid
- django celery的分布式异步之路(二) 高并发
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法