[Codechef TASTR] Level of Difference

Description

给定两个字符串,求恰好在一个字符串中出现过的本质不同的子串数量。

Solution

设 \(U(S)\) 表示在 \(S\) 中出现过的本质不同的子串集合,那么答案集合 \(A\)

\[A = U(P) + U(Q) - 2 U(P) \cap U(Q)
\]

\[|A| = |U(P)| + |U(Q)| - 2 |U(P) \cap U(Q)|
\]

根据容斥原理

\[U(P) \cap U(Q) = U(P) + U(Q) - U(P) \cup U(Q)
\]

于是

\[|A| = 2 |U(P) \cup U(Q)| - U(P) - U(Q)
\]

#include <bits/stdc++.h>
using namespace std;
#define int long long
struct sa
{
int n,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1000005],r[1000005],h[1000005],T;
char str[1000005];
long long ans; int cal()
{
memset(sa,0,sizeof sa);
memset(y,0,sizeof y);
memset(u,0,sizeof u);
memset(v,0,sizeof v);
memset(o,0,sizeof o);
memset(r,0,sizeof r);
memset(h,0,sizeof h); n=strlen(str+1); for(int i=1; i<=n; i++) u[str[i]]++;
for(int i=1; i<=m; i++) u[i]+=u[i-1];
for(int i=n; i>=1; i--) sa[u[str[i]]--]=i;
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]); for(int l=1; r[sa[n]]<n; l<<=1)
{
memset(u,0,sizeof u);
memset(v,0,sizeof v);
memcpy(o,r,sizeof r);
for(int i=1; i<=n; i++) u[r[i]]++, v[r[i+l]]++;
for(int i=1; i<=n; i++) u[i]+=u[i-1], v[i]+=v[i-1];
for(int i=n; i>=1; i--) y[v[r[i+l]]--]=i;
for(int i=n; i>=1; i--) sa[u[r[y[i]]]--]=y[i];
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+((o[sa[i]]!=o[sa[i-1]])||(o[sa[i]+l]!=o[sa[i-1]+l]));
}
{
int i,j,k=0;
for(int i=1; i<=n; h[r[i++]]=k)
for(k?k--:0,j=sa[r[i]-1]; str[i+k]==str[j+k]; k++);
} ans=(long long)n*(long long)(n+1)/(long long)2;
for(int i=1; i<=n; i++) ans-=(long long)h[i]; return ans;
}
} sa1,sa2,sa3; char s1[1000005],s2[1000005];
int l1,l2; signed main()
{
scanf("%s",s1+1);
scanf("%s",s2+1);
l1=strlen(s1+1);
l2=strlen(s2+1);
memcpy(sa1.str,s1,sizeof s1);
memcpy(sa2.str,s2,sizeof s2);
for(int i=1; i<=l1; i++) sa3.str[i]=s1[i];
sa3.str[l1+1]='$';
for(int i=1; i<=l2; i++) sa3.str[i+l1+1]=s2[i];
cout<<2ll*(sa3.cal()-(l1+1)*(l2+1))-sa1.cal()-sa2.cal()<<endl;
}

最新文章

  1. int与Integer的爱恨情仇
  2. Android开发7:简单的数据存储(使用SharedPreferences)和文件操作
  3. 神经网络模型之AlexNet的一些总结
  4. JavaScript中的事件
  5. iOS开发-Alpha,Hidden与Opaque区别
  6. master-slave(主/从)模式
  7. cocos2dx资源和脚本加密quick-lua3.3final
  8. 操作集合的工具类Collections
  9. PHP7 扩展之自动化测试
  10. 利用setTimeOut 和clearTimeOut 方法控制写一个 滑动导航显示不同信息的效果
  11. PHP Socket编程起步
  12. jQuery EasyUI求助
  13. JAVA之数组查询binarySearch()方法详解
  14. jquery解决onmouseover和onmouseout合用的bug问题
  15. 读书有感——《从毕业生到程序员使用C#开发商业软件》
  16. Vim安装YouCompletMe插件。
  17. Selenium自动化初级/中级网络授课班招生
  18. SpriteBuilder中的碰撞分类(Categories)和掩码(Masks)
  19. Android推送 百度云推送 入门篇
  20. java 删除整数元素集合中的元素

热门文章

  1. Mybaits(10)N+1问题
  2. MySQL系列(一):谈谈MySQL架构
  3. Docker容器Centos不能使用systemctl命令问题
  4. C#简单的LogHelper
  5. JAVA-&gt;查询并显示输入根目录下全部的文件所在目录路径
  6. CF1280E Kirchhoff&#39;s Current Loss
  7. Navigation Nightmare POJ - 1984 带权并查集
  8. udp_demo(傻瓜来回发送)
  9. springboot的yml配置文件里有多个参数的调用方式
  10. 【HTML】中国天气天气插件调用