博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LuoGuP3667
阅读量:5290 次
发布时间:2019-06-14

本文共 2298 字,大约阅读时间需要 7 分钟。

这题对我来说难的一批(题意理解错三遍,垃圾翻译,还是英文原题面好)
就是给你\(2n\)个串,要你找一个区间,使得前\(n\)个串的这个区间不能和后\(n\)个串中的区间有任何一个相同,求一个最短长度.
这显然可以二分,不过听取了\(dalao\)的建议,我选择了枚举左端点,二分右端点的方式.
怎么\(check\)呢?你把所有串\(hash\)一下,然后你显然可以任意查询某一个区间的\(hash\)值.
把后\(n\)个串的对应区间的\(hash\)值插入一个\(set\),直接查询就行了.
\(Code:\)

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MEM(x,y) memset ( x , y , sizeof ( x ) )#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)#define pii pair < int , int >#define X first#define Y second#define rint read
#define int long long#define pb push_back#define mid ( ( l + r ) >> 1 )using std::set ;using std::pair ;using std::max ;using std::min ;using std::priority_queue ;using std::vector ;using std::swap ;using std::sort ;using std::unique ;using std::greater ;template < class T > inline T read () { T x = 0 , f = 1 ; char ch = getchar () ; while ( ch < '0' || ch > '9' ) { if ( ch == '-' ) f = - 1 ; ch = getchar () ; } while ( ch >= '0' && ch <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ; ch = getchar () ; } return f * x ;}const int inf = 1e15 ;const int N = 1e3 + 100 ;const int base = 233 ;const int mod = 1e9 + 7 ;int n , m , g[N] , ans ; char s[N] ;unsigned int hash[N][N] ;std::set < int > st ;inline int query (int x , int l , int r) { return ( hash[x][r] - hash[x][l-1] * g[r-l+1] % mod + mod ) % mod ; }inline bool check (int l , int r) { st.clear () ; rep ( i , n + 1 , ( n << 1 ) ) st.insert ( query ( i , l , r ) ) ; rep ( i , 1 , n ) if ( st.find ( query ( i , l , r ) ) != st.end () ) return false ; return true ;}signed main (int argc , char * argv[]) { n = rint () ; m = rint () ; rep ( i , 1 , ( n << 1 ) ) { scanf ("%s" , s + 1 ) ; rep ( j , 1 , m ) hash[i][j] = ( hash[i][j-1] * base % mod + s[j] ) % mod ; } g[0] = 1 ; rep ( i , 1 , m ) g[i] = g[i-1] * base % mod ; ans = inf ; rep ( i , 1 , m ) { int l = i + 1 , r = m , res = ( m << 1 ) ; while ( l <= r ) { if ( check ( i , mid ) ) res = mid , r = mid - 1 ; else l = mid + 1 ; } ans = min ( ans , res - i + 1 ) ; } printf ("%lld\n" , ans ) ; return 0 ;}

转载于:https://www.cnblogs.com/Equinox-Flower/p/11499146.html

你可能感兴趣的文章
高可用Kubernetes集群-12. 部署kubernetes-ingress
查看>>
复利计算(结对编程)评论
查看>>
博客园 Mac客户端 2.0 正式发布!
查看>>
Java---容器基础总结
查看>>
清除Windows的DNS缓存
查看>>
发出HTTP请求并获得HTTP响应
查看>>
Eclipse使用Maven创建Dynamic Web Project
查看>>
Raphael实例
查看>>
模拟键盘输入
查看>>
基于插件架构的简单的Winform框架(上)
查看>>
一个很暴力很无奈的数据库随机数列生成问题
查看>>
re、词云
查看>>
WebService完成文件上传下载
查看>>
MFC控件编程之复选框单选框分组框
查看>>
phpcms流程
查看>>
js中typeof的用法汇总
查看>>
Xamarin XAML语言教程使用方法设置进度条进度
查看>>
使用Nginx转发TCP/UDP数据
查看>>
实现基于LNMP的电子商务网站
查看>>
Task与Thread间的区别
查看>>