2085: [Poi2010]Hamsters hash+倍增floyd
2016-03-07 13:51
260 查看
定义fk,i,j表示由第i个字符串开头第j个字符串结尾且一共有2k+1个子串的最短长度,然后倍增floyd转移一下。
#include<iostream> #include<cstdio> #include<cstring> #define U unsigned long long #define ll long long #define N 205 #define L 100005 #define base 233 #define inf 1e18 using namespace std; U T[L],hash [L]; int len ; ll f[32] ,A ,B ; int n,m; char s[L]; inline int read() { int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f; } inline ll calc(int i,int j) { int MAXN; if (i==j) MAXN=len[i]-1; else MAXN=min(len[i],len[j]); for (int k=MAXN;~k;k--) if (hash[i][len[i]]-hash[i][len[i]-k]*T[k]==hash[j][k]) return len[j]-k; } int main() { n=read(); m=read()-1; T[0]=1; for (int i=1;i<L;i++) T[i]=T[i-1]*base; for (int i=1;i<=n;i++) { scanf("%s",s+1); len[i]=strlen(s+1); for (int j=1;j<=len[i];j++) hash[i][j]=hash[i][j-1]*base+s[j]; } memset(f,0x3f,sizeof(f)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[0][i][j]=calc(i,j); for (int p=1;(1<<p)<=m;p++) for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[p][i][j]=min(f[p][i][j],f[p-1][i][k]+f[p-1][k][j]); int bit=0; for (;(1<<bit)<=m;bit++) if ((1<<bit)&m) { memcpy(A,f[bit],sizeof(A)); break; } for (bit++;(1<<bit)<=m;bit++) if ((1<<bit)&m) { memset(B,0x3f,sizeof(B)); for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) B[i][j]=min(B[i][j],min(A[i][k]+f[bit][k][j],f[bit][i][k]+A[k][j])); memcpy(A,B,sizeof(A)); } ll ans=inf; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) ans=min(ans,(ll)len[i]+A[i][j]); cout << ans << endl; return 0; }
相关文章推荐
- Shiro学习--Apache Shiro Architecture(Shiro架构)
- poj 1159 Palindrome 动态规划的三种解法
- Android应用架构之MVP实现
- Java异常体系结构
- javax.persistence.NonUniqueResultException: result returns more than one elements
- Hadoop op 1)
- 安全卫士第八天笔记
- 如何识别页面加载过程中出现的元素
- Block
- 使用C#向ACCESS中插入数据
- 使用RxBinding处理控件异步调用
- xamarin.forms 版本自动更新(针对android)
- hosts google
- MyBatis的学习总结六:Mybatis的缓存【参考】
- ZOJ3329
- oracle 新建表空间、用户
- Java实现冒泡排序算法
- Leetcode 1. Two Sum & 15. 3Sum & 16. 3Sum Closest & 18. 4Sum
- 界面传值
- 另类vs2015+xamarin 的android界面乱码 解决