BZOJ4180:字符串计数(SAM,二分,矩阵乘法)
Description
Input
Output
Sample Input
ABCCAD
Sample Output
HINT
Solution
Code
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<queue>
- #define N (200009)
- #define LL long long
- using namespace std;
- LL n,id;
- char s[N];
- queue<int>Q;
- int dis[N],vis[N];
- struct Matrix
- {
- LL m[][];
- Matrix(){memset(m,,sizeof(m));}
- Matrix operator * (const Matrix &b) const
- {
- Matrix c;
- for (int i=; i<; ++i)
- for (int j=; j<; ++j)
- c.m[i][j]=1e18;
- for (int k=; k<; ++k)
- for (int i=; i<; ++i)
- for (int j=; j<; ++j)
- c.m[i][j]=min(c.m[i][j],m[i][k]+b.m[k][j]);
- return c;
- }
- }A,G;
- Matrix Qpow(Matrix a,LL b)
- {
- Matrix ans;
- for (int i=; i<; ++i) ans.m[i][i]=;
- while (b)
- {
- if (b&) ans=ans*a;
- a=a*a; b>>=;
- }
- return ans;
- }
- struct SAM
- {
- int son[N][],fa[N],step[N];
- int p,q,np,nq,last,cnt;
- SAM(){last=cnt=;}
- void Insert(int x)
- {
- p=last; np=last=++cnt; step[np]=step[p]+;
- while (p && !son[p][x]) son[p][x]=np, p=fa[p];
- if (!p) fa[np]=;
- else
- {
- q=son[p][x];
- if (step[q]==step[p]+) fa[np]=q;
- else
- {
- nq=++cnt; step[nq]=step[p]+;
- memcpy(son[nq],son[q],sizeof(son[q]));
- fa[nq]=fa[q]; fa[q]=fa[np]=nq;
- while (son[p][x]==q) son[p][x]=nq, p=fa[p];
- }
- }
- }
- void Build_Matrix()
- {
- for (int i=; i<; ++i)
- for (int j=; j<; ++j)
- A.m[i][j]=1e18;
- for (int s=; s<; ++s)
- {
- while (!Q.empty()) Q.pop();
- memset(vis,false,sizeof(vis));
- vis[son[][s]]=true;
- Q.push(son[][s]); dis[son[][s]]=;
- while (!Q.empty())
- {
- int x=Q.front(); Q.pop();
- for (int i=; i<; ++i)
- if (son[x][i] && !vis[son[x][i]])
- vis[son[x][i]]=true,Q.push(son[x][i]),dis[son[x][i]]=dis[x]+;
- else A.m[s][i]=min(A.m[s][i],(LL)dis[x]);
- }
- }
- }
- }SAM;
- LL check(LL x)
- {
- LL Min=1e18;
- G=Qpow(A,x);
- for (int i=; i<; ++i)
- for (int j=; j<; ++j)
- Min=min(Min,G.m[i][j]);
- return Min>=n;
- }
- int main()
- {
- scanf("%lld%s",&n,s);
- for (int i=,l=strlen(s); i<l; ++i)
- SAM.Insert(s[i]-'A');
- SAM.Build_Matrix();
- LL l=,r=1e18,ans;
- while (l<=r)
- {
- LL mid=(l+r)>>;
- if (check(mid)) ans=mid,r=mid-;
- else l=mid+;
- }
- printf("%lld\n",ans);
- }
BZOJ4180:字符串计数(SAM,二分,矩阵乘法)的更多相关文章
- 【BZOJ 4180】 4180: 字符串计数 (SAM+二分+矩阵乘法)
4180: 字符串计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 164 Solved: 75 Description SD有一名神犇叫做Oxe ...
- BZOJ 4180: 字符串计数 后缀自动机 + 矩阵乘法 + 二分(神题)
Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999. 他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C ...
- 【BZOJ-4180】字符串计数 后缀自动机 + 矩阵乘法
4180: 字符串计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 146 Solved: 66[Submit][Status][Discuss] ...
- POJ 3233 Matrix Power Series 二分+矩阵乘法
链接:http://poj.org/problem?id=3233 题意:给一个N*N的矩阵(N<=30),求S = A + A^2 + A^3 + - + A^k(k<=10^9). 思 ...
- [BZOJ4180] 字符串计数
膜一发KsCla巨佬 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5 ...
- 【清澄A1333】【整体二分+二维树状数组】矩阵乘法(梁盾)
试题来源 2012中国国家集训队命题答辩 问题描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入格式 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共 ...
- BZOJ 2738: 矩阵乘法 [整体二分]
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 愚蠢的名字...... 整体二分,影响因子就是矩阵里的数 把$\le mid$的矩阵元素加到二维树状数组里然后询问分成两组就行 ...
- BZOJ_2738_矩阵乘法_整体二分
BZOJ_2738_矩阵乘法_整体二分 Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下 ...
- BZOJ_4002_[JLOI2015]有意义的字符串_矩阵乘法
BZOJ_4002_[JLOI2015]有意义的字符串_矩阵乘法 Description B 君有两个好朋友,他们叫宁宁和冉冉.有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求 Input 一行 ...
随机推荐
- Java多态-如何理解父类引用指向子类对象
java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过 Cat c = new ...
- SpringMVC的controller层接收来自jsp页面通过<a href="/user/userUpdateInfo/>的中文乱码问题
这种情况是,jsp页面的中文正常显示,数据的中文也是正常显示,但是在Controller层接收到的中文是乱码,如下图所示: 解决方法:在Controller层对前台传递的中文乱码进行处理,将它转换成u ...
- java自学-基本数据类型
java中也有对数据的运算处理,java中数据分为常量和变量,常量就是直接固定不变的数据,变量是数据可能发生改变的数据,如下: int a=0; a=1+1; 上边代码,a就是变量,初始为0,接下来 ...
- JAVA非静态成员变量之死循环
1.非静态成员变量 当成员变量为非静态成员变量且对当前类进行实例化时,将会产生死循环 例子: public class ConstructorCls { private ConstructorCls ...
- 为什么要用 C# 来作为您的首选编程语言
因为您可以用,并且也是您的最佳选择!之所以可用,是因为 C# 能够很好地在 Mac.Linux.Android 和 iOS 上运行(对了,还有 Windows):它可以在您最喜爱的编辑器上运行:它在一 ...
- Linux学习7-Linux常用命令(3)
文件处理命令 命令名称:touch 命令英文原意:touch 命令所在路径:/bin/touch 执行权限:所有用户 功能描述:创建空文件 语法:touch[文件名] 范例: $tou ...
- 用python写桌面天气预报,自己的学习曲线。
自从接触python,就被他优雅而简洁的代码所吸引. 举个例子: arr , , , , , , , , , , , , , ] ] 如果用其他语言来写的吗,不会这么简洁,美观. python还有 ...
- python中作用域
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的. 函数定义了本地作用域,而模块定义的是全局作用域.如果想要在函数内定义全局作用域,需要加上global修饰符. 变量名解析:LEG ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
- JavaScript 常见面试题
此文内容多为 JavaScript 对数组理解及运用. 1.如何消除一个数组里面重复的元素? var arr = [1, 2, 3, 3, 4, 4, 5, 5, 6, 1]; var newArr ...