hdu 4029

题意:给你一个字符矩阵,统计不同的子矩阵的个数;

分析:枚举子矩阵的宽度w,对于每一个w,将每一行长度可以是w的字符串HASH成一个值,然后用map标记,因为宽确定了,hash完之后,然后如果相等就表示此时长度为w的字串

相等,将他们按照每一列排序形成一个字符串,此时如果莫两个长度为x的子串相等就表示此时x*w的子矩阵相同,

这样就是统计m个字符串的不同的子串的个数,这个是SA的论文题;n^3*logn

HASH会冲突,SEED选择很重要,当然也可以用2个SEED,这样冲突的概率就很小很小了;

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<map>
#define mk make_pair using namespace std;
typedef unsigned long long ULL;
typedef pair<ULL,ULL> pUU;
const int N = +;
const int M = +;
const int SEED[]= {,};
char s[M][M];
ULL hash[][M][M],X[][M];
int n,m;
map<pUU,int> mp;
int str[N];
struct Suffix_Array {
int a1[N],a2[N],c[N],sa[N],SA[N],*x,*y,n,m;
int height[N],*rank;
void sort(){
for (int i = ; i < m; i++) c[i] = ;
for (int i = ; i < n; i++) c[ x[i] ] ++;
for (int i = ; i < m; i++) c[i+] += c[i];
for (int i = n-; i >= ; i--) SA[ --c[x[sa[i]]] ] = sa[i];
}
void build_SA(int s[],int _n,int _m) {
n = _n; m = _m;
x = a1; y = a2; x[n] = y[n] = -;
for (int i = ; i < n; i++) x[i] = s[i], sa[i] = i;
sort();
for (int k = ; k <= n; k <<= ) {
int p = ;
for (int i = n-k; i < n; i++) sa[ p++ ] = i;
for (int i = ; i < n; i++) if (SA[i] >= k) sa[ p++ ] = SA[i] - k;
sort();
p = ; y[SA[]] = ;
for (int i = ; i < n; i++) {
if ( x[SA[i-]] != x[SA[i]] || x[SA[i-]+k] != x[SA[i]+k] ) p++;
y[SA[i]] = p;
}
swap(x,y);
if (p+ == n) break;
m = p + ;
}
rank = x; getHeight(s);
}
void getHeight(int s[]){
int k = ;
for (int i = ; i < n; i++) {
if (k) k--;
if (rank[i] == ) continue;
int j = SA[rank[i] - ];
while ( s[j+k] && s[i+k] == s[j+k]) k++;
height[ rank[i] ] = k;
}
height[n] = ;
}
void check(){
for (int i = ; i < n; i++) cout<<SA[i]<<" "; cout<<endl;
for (int i = ; i < n; i++) cout<<rank[i]<<" "; cout<<endl;
for (int i = ; i < n; i++) cout<<height[i]<<" "; cout<<endl;
}
}H; void init(){
// 会用到的一定要清空;
for (int k = ; k < ; k++)
for (int i = ; i < n; i++) {
hash[k][i][m] = ;//会用到,如果不清空会wa;
hash[k][i][m-] = s[i][m-] - 'A';
for (int j = m-; j >= ; j--) {
hash[k][i][j] = hash[k][i][j+] * SEED[k] + s[i][j] - 'A';
}
}
X[][] = X[][] = ;
for (int k = ; k < ; k++)
for (int i = ; i <= m; i++) {
X[k][i] = X[k][i-] * SEED[k];
}
} int idx[N];
int find(int n){
int ret = idx[H.SA[]];
for (int i = ; i < n; i++){
ret += idx[H.SA[i]] - H.height[i];
}
return ret;
}
void solve(){
int ret = ;
int cnt, tot;
for (int w = ; w <= m; w++) {
cnt = , tot = ;
mp.clear();
for (int j = ; j+w- < m; j++){
for (int i = ; i < n; i++) {
ULL tmp1 = hash[][i][j] - hash[][i][j+w] * X[][w];
ULL tmp2 = hash[][i][j] - hash[][i][j+w] * X[][w]; if (mp.find(mk(tmp1,tmp2)) == mp.end()){
mp[mk(tmp1,tmp2)] = tot++;
}
idx[cnt] = n - i;
str[cnt++] = mp[mk(tmp1,tmp2)];
}
idx[cnt] = ;
str[cnt++] = tot++;
}
H.build_SA(str,cnt,tot);
// H.check();
ret += find(cnt);
}
printf("%d\n",ret); }
int main(){
int T, cas = ; scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
for (int i = ; i < n; i++) {
scanf("%s",s[i]);
}
init();
printf("Case #%d: ",++cas);
solve();
}
return ;
}

UVA 10829

题意:给你一个串,求形如UVU的子串的个数,其中v的长度为g;

思路:枚举u的长度i,将串每i个字符一组,如:

bbaabaaa     i == 2

bb |  aa | ba | aa

01   2 3  4 5  6 7

 #include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N = +;
struct SA{
int a1[N],a2[N],c[N],sa[N],SA[N],*x,*y,n,m;
int height[N],*rank;
int f[][N];
void sort() {
for (int i = ; i < m; i++) c[i] = ;
for (int i = ; i < n; i++) c[ x[i] ] ++;
for (int i = ; i < m; i++) c[i+] += c[i];
for (int i = n-; i >= ; i--)
SA[ --c[x[sa[i]]] ] = sa[i];
}
void build_SA(char *s,int _n,int _m){
n = _n; m = _m;
x = a1; y = a2; x[n] = y[n] = -;
for (int i = ; i < n; i++) x[i] = s[i], sa[i] = i;
sort();
for (int k = ; k <= n; k <<= ) {
int p = ;
for (int i = n-k; i < n; i++) sa[p++] = i;
for (int i = ; i < n; i++) if (SA[i] >= k) sa[p++] = SA[i] - k;
sort();
p = ; y[SA[]] = ;
for (int i = ; i < n; i++) {
if (x[SA[i-]] != x[SA[i]] || x[SA[i-]+k] != x[SA[i]+k] ) p++;
y[SA[i]] = p;
}
swap(x,y);
if (p+ == n) break;
m = p+;
}
rank = x; getHeight(s);
}
void getHeight(char *s) {
int k = ;
for (int i = ; i < n; i++) {
if (k) k--;
if (rank[i] == ) continue;
int j = SA[rank[i]-];
while (i + k < n && j + k < n && s[i+k] == s[j+k]) k++;
height[ rank[i] ] = k;
}
height[n] = ;
}
void initRMQ(){
for (int i = ; i < n; i++) f[][i] = height[i];
for (int i = ; (<<i) < n; i++) {
for (int j = ; j+(<<i)- < n; j++) {
f[i][j] = min(f[i-][j], f[i-][j+(<<i>>)]);
}
}
}
int lcp(int a,int b) {
a = rank[a]; b = rank[b];
if (a > b) swap(a,b);
a++;
int t = ;
while ((<<t) <= (b - a + )) t++;
t--;
return min(f[t][a], f[t][b - (<<t) + ]);
}
void check(){
// build_SA("aabaab",6,220);
for (int i = ; i < n; i++) {
cout<<SA[i]<<" ";
}cout<<endl;
for (int i = ; i < n; i++) {
cout<<rank[i]<<" ";
}cout<<endl;
for (int i = ; i < n; i++) {
cout<<height[i]<<" ";
}cout<<endl;
}
}H1,H2;
int g;
void solve(){
int ret = ;
int len =strlen(s);
for (int i = ; i < len; i++) {
s2[i] = s[len - i - ];
}
H1.build_SA(s,len,);
H2.build_SA(s2,len,);
H1.initRMQ(); H2.initRMQ();
for (int i = ; i <= (len - g)/; i++) {
for (int j = ; j + i + g < len; j += i) {
int l = j, r = j + i + g;
int u, v, w = ;
u = H1.lcp(l,r); v = H2.lcp(len - - l,len - - r);
// cout<<" **** "<<i<<endl;
// cout<<l<<" "<<r<<endl;
// cout<<u<<" "<<v<<endl;
if (v <= i) w = v;
else w = ;
if (u <= *i -) w += u;
else w += *i - ;
ret += max(,w-i);
//cout<<w<<" "<<ret<<endl;
}
}
printf("%d\n",ret);
}
int main(){
// H.check();
int T, cas = ; scanf("%d",&T);
while (T--) {
scanf("%d%s",&g,s);
printf("Case %d: ",++cas);
solve(); }
return ;
}

poj 3415

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int N = *+;
struct Point{
int val,cnt;
Point(){}
Point(int x,int y):val(x),cnt(y){}
};
int k;
struct dequeue{
int head,tail;
Point q[N];
void init(){
head = ; tail = ;
}
void push(Point pp,LL &sum){
while (head <= tail && pp.val <= q[tail].val) {
sum -= (LL)(q[tail].val - k + ) * q[tail].cnt;
pp.cnt += q[tail].cnt;
tail--;
}
sum += (LL)(pp.val - k + ) * pp.cnt;
q[++tail] = pp;
}
}R; struct SA{
int a1[N],a2[N],c[N],sa[N],SA[N],*x,*y,n,m;
int height[N],*rank;
void sort(){
for (int i = ; i < m; i++) c[i] = ;
for (int i = ; i < n; i++) c[ x[i] ]++;
for (int i = ; i < m; i++) c[i+] += c[i];
for (int i = n-; i >= ; i--)
SA[ --c[x[sa[i]]] ] = sa[i];
}
void build_SA(char *s,int _n,int _m){
n = _n; m = _m;
x = a1; y = a2; x[n] = y[n] = -;
for (int i = ; i < n; i++) x[i] = s[i], sa[i] = i;
sort();
for (int k = ; k <= n; k <<= ) {
int p = ;
for (int i = n-k; i < n; i++) sa[ p++ ] = i;
for (int i = ; i < n; i++) if (SA[i] >= k) sa[ p++ ] = SA[i] - k;
sort();
p = ; y[SA[]] = ;
for (int i = ; i < n; i++) {
if ( x[SA[i-]] != x[SA[i]] || x[SA[i-]+k] != x[SA[i]+k] ) p++;
y[SA[i]] = p;
}
swap(x,y);
if (p+ == n) break;
m = p + ;
}
rank = x; getHeight(s);
}
void getHeight(char *s) {
int k = ;
for (int i = ; i < n; i++) {
if (k) k--;
if (rank[i] == ) continue;
int j = SA[rank[i] - ];
while (s[i+k] == s[j+k] && i+k < n && j+k < n) k++;
height[ rank[i] ] =k;
}
height[n] = ;
}
int idx(int x,int mid) {
if (x < mid) return ;
return ;
}
LL solve(int limt,int mid,int tar){//tar in queue
R.init();
LL ret = ;
LL sum = ;
for (int i = ; i <= n; i++) {
if (height[i] >= limt){
// cout<<SA[i-1]<<" ";
if (idx(SA[i-],mid) == tar) {
R.push(Point(height[i],),sum);
}else {
ret += sum;
R.push(Point(height[i],),sum);
}
}else {
//cout<<SA[i-1]<<" **** "<<endl;
if (idx(SA[i-],mid) != tar){
ret += sum;
}
R.init();
sum = ;
}
}
return ret;
}
void check(){
// build_SA("aabaab",6,255);
for (int i = ; i < n; i++) cout<<SA[i]<<" ";cout<<endl;
for (int i = ; i < n; i++) cout<<rank[i]<<" ";cout<<endl;
for (int i = ; i < n; i++) cout<<height[i]<<" ";cout<<endl;
}
}H;
int mid,len;
char s[N];
void solve(){
LL ret = ;
//H.check();
ret += H.solve(k,mid,);
//cout<<ret<<endl;
ret += H.solve(k,mid,);
printf("%lld\n",ret);
}
int main(){
// H.check();
while (~scanf("%d",&k),k) {
scanf("%s",s);
mid = strlen(s);
s[mid] = '#';
scanf("%s",s+mid+);
len = strlen(s);
// cout<<s<<endl;
H.build_SA(s,len,);
solve();
}
return ;
}
/*
2
aababaa
abaabaa
1
xx
xx
0
*/

SA的更多相关文章

  1. QL Server 2008 所有账号丢失sysadmin权限,sa账号亦没有开启,该如何解决??

    1. 用Run as a administrator打开命令提示符里输入NET STOP MSSQLSERVER, 即停止MSSQLSERVER运行. 2. 在命令提示符里输入 NET START M ...

  2. 没有了SA密码,无法Windows集成身份登录,DBA怎么办?

    一同事反馈SQL无法正常登录了,以前都是通过windows集成身份验证登录进去的(sa密码早忘记了),今天就改了服务器的机器名,现在无论如何都登录不进去. SQL登录时如果采用windows集成身份验 ...

  3. SqlServer windowss身份登陆和sa身份登陆

    今天重新装了系统,但是计算机名变了,于是修改了计算机名,然后装了SQLSEVER,安装完成后登录,发现无论用WINDOWS身份还是SQLSERVER身份都登录不了 1.先说说sqlserver身份登录 ...

  4. 【JBOSS】User not found SA

    启动JBOSS 发现报User not found: SA 错误, 找了老半天才找到处理方法,异常日志如下: java.sql.SQLException: User not found: SA at ...

  5. Cannot set a credential for principal 'sa'. (Microsoft SQL Server,错误: 15535)

    在SQL SERVER 2008上上禁用sa登录时,遇到下面错误:"Cannot set a credential for principal 'sa'. (Microsoft SQL Se ...

  6. ASP.NET连接数据库时,提示“用户 'sa' 登录失败原因: 未与信任 SQL Server 连接相关联

    用ASP.NET连接数据库时,提示"用户 'sa' 登录失败.原因: 未与信任 SQL Server 连接相关联.".解决方法:首先检查是不是web.config文件内的用户名密码 ...

  7. Sa yo na ra

    总想记点些什么. 都快忘了当初是为什么来到这里呢... 2014年10月,友人给我介绍了一门编程竞赛ACM,并给我演示了一下A+B.于是我知道了ACM的含义. 2014年12月,开始水入门题. 201 ...

  8. SQL_Server_2008修改sa密码的方法

    转载自:http://blog.csdn.net/templar1000/article/details/20211191 1. 先用Window身份验证方式登陆进去,选择数据库实例,右键选择属性—— ...

  9. 高级Linux SA需要会做的事情

    高级Linux SA需要会做的事情:linux---------系统安装(光盘或自动化安装)linux---------系统常用工具安装(sudo,ntp,yum,rsync,lrzsz syssta ...

  10. 修改msde登录方式,设置sa密码为空

    md, 记不得msde怎么修改密码, 每次都要去baidu, 下了个鸟破软件,修改msde密码, 还流氓的安装了360, 写了个批处理,留在这里: net stop MSSQLSERVERreg ad ...

随机推荐

  1. poj 1934(LCS)

    转自:http://www.cppblog.com/varg-vikernes/archive/2010/09/27/127866.html 1)首先按照常规的方法求出最长公共子序列的长度也就是用O( ...

  2. WebForm页面运行机制

    阅读目录 开始 WebForm前台与后台的关系及运行原理 前台页面 <% @ Page Language="C#" AutoEventWireup="true&qu ...

  3. Asp.Net保存session的三种方法

    C#中保存Session的三种方法及Web.Config设置 1.保存session到sql server,需要指定Sql Server服务器,这种方法因为要读写数据库最慢 <sessionSt ...

  4. Android 编程下两种方式注册广播的区别

    常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接收到,它的注册方式就是在你应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称 ...

  5. ecshop显示所有分类树栏目

    1.找到 category.php 和goods.php 两个文件修改: $smarty->assign('categories', get_categories_tree(0)); // 分类 ...

  6. android 语言切换过程分析

    android 语言切换过程分析 2014-02-27 18:13 1207人阅读 评论(0) 收藏 举报 语言切换android语言切换android改变语言 最近在看一个bug,系统切换语言后,本 ...

  7. 基于HTTP的直播点播HLS

             HLS(HTTP Live Streaming) 是Apple在2009年发布的,可以通过普通的web服务器进行分发的新型流媒体协议.苹果官方对于视频直播服务提出了 HLS 解决方案 ...

  8. Effective java笔记7--线程

    一.对可共享数据的同步访问 synchronized关键字可以保证在同一时刻,只有一个线程在执行一条语句,或者一段代码块.正确地使用同步可以保证其他任何方法都不会看到对象处于不一致的状态中,还能保证通 ...

  9. YII 配置文件

    用YIIFramework的库开发 .... Yii::createWebApplication($config); //没有run Yii::import(class1,true),在将class1 ...

  10. 代码所见所得方式发布.xml

    pre{ line-height:1; color:#b836b3; background-color:#000000; font-size:16px;}.sysFunc{color:#19ef0b; ...