思路

广义SAM

把两个字符串建成广义SAM,然后统计两个SAM中相同节点的endpos大小乘积即可

记得开long long

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 800100;
int endpos[MAXN][2],trans[MAXN][26],suflink[MAXN],maxlen[MAXN],minlen[MAXN],Nodecnt,in[MAXN],n;
char s[MAXN];
int New_state(int _maxlen,int _minlen,int *_trans,int _suflink){
++Nodecnt;
maxlen[Nodecnt]=_maxlen;
minlen[Nodecnt]=_minlen;
if(_trans)
for(int i=0;i<26;i++)
trans[Nodecnt][i]=_trans[i];
suflink[Nodecnt]=_suflink;
return Nodecnt;
}
int add_len(int u,int c,int inq){
if(trans[u][c]){
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
endpos[v][inq]++;
return v;
}
else{
int y=New_state(maxlen[u]+1,0,trans[v],suflink[v]);
endpos[y][inq]++;
suflink[v]=y;
minlen[v]=maxlen[y]+1;
while(u&&(trans[u][c]==v)){
trans[u][c]=y;
u=suflink[u];
}
minlen[y]=maxlen[suflink[y]]+1;
return y;
}
}
else{
int z=New_state(maxlen[u]+1,0,NULL,0);
endpos[z][inq]++;
while(u&&(trans[u][c]==0)){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
minlen[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
suflink[z]=v;
minlen[z]=maxlen[v]+1;
return z;
}
int y=New_state(maxlen[u]+1,0,trans[v],suflink[v]);
suflink[v]=suflink[z]=y;
minlen[v]=minlen[z]=maxlen[y]+1;
while(u&&(trans[u][c]==v)){
trans[u][c]=y;
u=suflink[u];
}
minlen[y]=maxlen[suflink[y]]+1;
return z;
}
}
queue<int> q;
void get_sz(void){
for(int i=2;i<=Nodecnt;i++)
in[suflink[i]]++;
for(int i=0;i<=Nodecnt;i++)
if(!in[i])
q.push(i);
while(!q.empty()){
int x=q.front();
q.pop();
endpos[suflink[x]][0]+=endpos[x][0];
endpos[suflink[x]][1]+=endpos[x][1];
in[suflink[x]]--;
if(!in[suflink[x]])
q.push(suflink[x]);
}
}
long long ans=0;
int main(){
scanf("%s",s+1);
n=strlen(s+1);
Nodecnt=1;
int last=1;
for(int i=1;i<=n;i++)
last=add_len(last,s[i]-'a',0);
scanf("%s",s+1);
n=strlen(s+1);
last=1;
for(int i=1;i<=n;i++)
last=add_len(last,s[i]-'a',1);
get_sz();
for(int i=2;i<=Nodecnt;i++){
ans+=(long long)((long long)maxlen[i]-minlen[i]+1)*(long long)((long long)endpos[i][0]*endpos[i][1]);
}
printf("%lld\n",ans);
return 0;
}

P3181 [HAOI2016]找相同字符的更多相关文章

  1. bzoj4566 / P3181 [HAOI2016]找相同字符

    P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机.   我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...

  2. Luogu P3181 [HAOI2016]找相同字符 广义$SAM$

    题目链接 \(Click\) \(Here\) 设一个串\(s\)在\(A\)中出现\(cnt[s][1]\)次,在\(B\)中出现\(cnt[s][2]\)次,我们要求的就是: \[\sum cnt ...

  3. [洛谷P3181][HAOI2016]找相同字符

    题目大意:给你两个字符串,求从两个字符串中各选择一个字串使得这两个字串相同的方案数. 题解:建广义$SAM$,对每个点求出在第一个串中出现次数和第二个串中出现次数,乘起来就行了 卡点:无 C++ Co ...

  4. BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 275  Solved: 155[Submit][Statu ...

  5. 【BZOJ4566】[HAOI2016]找相同字符

    [BZOJ4566][HAOI2016]找相同字符 题面 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 其中\(1\le ...

  6. [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1212  Solved: 694[Submit][Stat ...

  7. 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈

    [BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...

  8. bzoj 4566 [Haoi2016]找相同字符SA

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 128  Solved: 75[Submit][Status ...

  9. [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 861  Solved: 495[Submit][Statu ...

随机推荐

  1. bypass safedog upload

    这里附上两个payload: Content-Disposition: form-data; name=”up_picture”; filename=”[回车]1.php” Content-Dispo ...

  2. Background removal with deep learning

    [原文链接] Background removal with deep learning   This post describes our work and research on the gree ...

  3. 【node】mongoose的基本使用

    1.安装mongoose npm install mongoose 2.启动数据库 mongod --dbpath d:\data\db 3.引入mongoose模块并连接数据库 const mong ...

  4. 解决mapper绑定异常:nested exception is org.apache.ibatis.binding.BindingException:

    原因: 此异常的原因是由于mapper接口编译后在同一个目录下没有找到mapper映射文件而出现的.由于maven工程在默认情况下src/main/java目录下的mapper文件是不发布到targe ...

  5. C#遍历枚举(Enum)值

    foreach (object o in Enum.GetValues(typeof(EmpType))) { Console.WriteLine("{0}:{1}", o, En ...

  6. 解决url传中文参数问题

    项目中要做一个表格导出功能,用的是location.url传值给后台导出表格数据.由于传中文会出现乱码现象.故需要给参数转码,具体如下: 对于url要传的中文参数进行两次编码(注意是两次),即enco ...

  7. RTOS 和中断之间要注意的

    #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRI ...

  8. 审核被拒:1. 1 Safety: Objectionable Content ;3. 1.1 Business: Payments - In-App Purchase ;4. 3 Design: Spam ;5. 1.1 Legal: Privacy - Data Collection and Storage

    1. 1 Safety: Objectionable Content                          有人民币符号—隐藏收费课程 3. 1.1 Business: Payments ...

  9. JAVA-数据库之MySQL与JDBC驱动下载与安装

    相关资料:<21天学通Java Web开发> MySQL下载地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-wi ...

  10. int bool 字符串 列表 字典 集合

    1.int和bool 输出i的最大二进制位数inti = 1000 print(i.bit_length()) 2. str int bool list set dict  tuple 相互转换 pr ...