首页 > 其他分享 >模板2

模板2

时间:2024-09-01 18:36:04浏览次数:2  
标签:int void ++ trs mod 模板 rk

字符串

KMP

nxt[i]: $b[1:i]$ 的最长 border $b[1:nxt_i]$,且 $nxt_i<i$。

void init(){
int p=0;
F(i,2,m){
while(p&&b[p+1]!=b[i]) p=nxt[p];//p+1 尝试与 i 匹配
if(b[p+1]==b[i]) p++;
nxt[i]=p;
}
}
void kmp(){
int p=0;
F(i,1,n){
while(p&&(p==m||b[p+1]!=a[i]) p=nxt[p];//p==m
if(b[p+1]==a[i]) p++;
f[i]=p;
}
}

Z 函数

$z_1=0$。

z[i]:$b[i:n]$ 与 b 的 LCP 长度。

void z_init(){
z[1]=0;//
for(int i=2,l=0,r=0;i<=m;i++){
if(i>r) z[i]=0;
else z[i]=min(z[i-l+1],r-i+1);
while(i+z[i]<=m&&b[1+z[i]]==b[i+z[i]]) z[i]++;
if(i+z[i]-1>r) l=i,r=i+z[i]-1;
}
}
void z_alg(){
for(int i=1,l=0,r=0;i<=n;i++){
if(i>r) p[i]=0;
else p[i]=min(z[i-l+1],r-i+1);
while(i+p[i]<=n&&b[1+p[i]]==a[i+p[i]]) p[i]++;
if(i+p[i]-1>r) l=i,r=i+p[i]-1;
}
}

Manacher

p[i]:以 $i$ 为中心的最长回文半径。$[i-p_i+1,i+p_i+1]$ 为回文串。

void init(){
int m=0;
s[++m]='#';//s[0]='(',s[1]='#'
F(i,1,n) s[++m]=a[i],s[++m]='#';
s[0]='(';s[m+1]=')';
}
void manacher(){
p[1]=1;
for(int i=2,k=1;i<=m;i++){//k=1,当前最优端点属于 1 的回文串
if(i>k+p[k]-1) p[i]=1;
else p[i]=min(k+p[k]-i,p[2*k-i]);
while(s[i-p[i]]==s[i+p[i]]) p[i]++;
if(i+p[i]>k+p[k]) k=i;
}
}

AC自动机

fail:指向某状态所表示的字符串的最长后缀。

//AC
struct node{
int trs[26],fail;
}t[N];
int tot=1;//p=1 is used
void ins(){
int p=1;
F(i,1,n){
int c=s[i]-'a';
if(!t[p].trs[c]) t[p].trs[c]=++tot;
p=t[p].trs[c];
}
}
void bd(){
F(i,0,25) t[0].trs[i]=1;
t[1].fail=0;

queue<int>q;
q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
F(i,0,25){
int &v=t[u].trs[i];//&v
if(v) t[v].fail=t[t[u].fail].trs[i],q.push(v);
else v=t[t[u].fail].trs[i];
}
}
}

SA

//SA
int m=256;
int sa[N],rk[N],tmp_rk[N],id[N],ct[N],px[N],ht[N];
bool same(int x,int y,int k){
int p=x+k<=n?tmp_rk[x+k]:-1,
q=y+k<=n?tmp_rk[y+k]:-1;
return tmp_rk[x]==tmp_rk[y]&&p==q;
}
void init(){
F(i,1,n) rk[i]=s[i];
F(i,1,n) ct[rk[i]]++;
F(i,1,m) ct[i]+=ct[i-1];
for(int i=n;i>=1;i--) sa[ct[rk[i]]--]=i;

for(int k=1,p=0;k<n;k<<=1,m=p){
p=0;
F(i,n-k+1,n) id[++p]=i;
F(i,1,n)if(sa[i]>k) id[++p]=sa[i]-k;

F(i,0,m) ct[i]=0;
F(i,1,n) ct[px[i]=rk[id[i]]++;
F(i,1,m) ct[i]+=ct[i-1];
for(int i=n;i>=1;i--) sa[ct[px[i]]--]=id[i];

F(i,1,n) tmp_rk[i]=rk[i];
p=0;
F(i,1,n) rk[sa[i]]=same(sa[i],sa[i-1],k)?p:++p;//
}
for(int i=1,h=0;i<=n;i++){
if(h) h--;
int j=sa[rk[i]-1];
while(s[i+h]==s[j+h]) h++;
ht[rk[i]]=h;//
}
}

SAM

//SAM
const int SZ=N<<1;
int tot=1,las=1;
struct node{
int trs[26],lk,mxl;
}t[SZ];
void extend(int c){
int p=las,np=las=++tot;
t[np].mxl=t[p].mxl+1;

for(;!t[p].trs[c];p=t[p].lk) t[p].trs[c]=np;
if(!p) t[np].lk=1;
else{
int q=t[p].trs[c];
if(t[q].mxl==t[p].mxl+1) t[np].lk=q;
else{
int nq=++tot;t[nq]=t[q];
t[nq].mxl=t[q].mxl+1;
t[q].lk=t[np].lk=nq;
for(;t[p].trs[c]==q;p=t[p].lk) t[p].trs[c]=nq;
}
}
}

数论

拉格朗日插值

==求点值==:

$O(n^2)$。

int lag(int k){
ll ans=0;
F(i,1,c+1){
ll p=1,q=1;
F(j,1,c+1)if(i^j){
p=p*(k-x[j])%mod;
q=q*(x[i]-x[j])%mod;
}
ans=(ans+p*inv(q)%mod*y[i])%mod;//y[i]
}
return (ans+mod)%mod;
}

==已知的横坐标连续时求点值==:

$O(n)$。

int lag(int k){
if(k<=c+1) return y[k];

pre[0]=1;
F(i,1,c+1) pre[i]=pre[i-1]*(k-i)%mod;
suf[c+1+1]=1;
for(int i=c+1;i>=1;i--) suf[i]=suf[i+1]*(k-i)%mod;

F(i,1,c+1){
ll val=pre[i-1]*suf[i+1]%mod*ifac[i-1]%mod*ifac[c+1-i]%mod*y[i]%mod;
if(val<0) val+=mod;
if((c+1-i)&1) dec(ans,val);
else add(ans,val);
}
return ans;
}

==横坐标连续时求系数==:

$O(n^2)$。

void calc(int *f,int *g,int n){
h[0]=1;
F(i,1,n+1) for(int j=i;j>=0;j--)
h[j]=((j?h[j-1]:0)+(mod-h[j])*i)%mod;
F(i,1,n+1){
memcpy(tmp,h,sizeof(tmp));
F(j,0,n+1)
tmp[j]=((j?tmp[j-1]:0)-tmp[j]+mod)*inv[i]%mod;
int sum=g[i];
F(j,1,n+1)if(j^i)
sum=sum*(i>j:inv[i-j]:mod-inv[j-i])%mod;
F(j,0,n) f[j]=(f[j]+sum*tmp[j])%mod;
}
}

 

子集DP

for (int i = 0; i < m; i ++)
for (int S = 0; S < (1 << m); S ++)
if (S >> i & 1) // f[S] <- f[S ^ (1 << i)]

线性筛素数

int pClock, prime[N], fac[N];

void sieve(const int &N) {
for (int i = 2; i <= N; i ++) {
if (!fac[i]) fac[i] = i, prime[++ pClock] = i;
for (int j = 1; j <= pClock; j ++) {
if (prime[j] > fac[i] || prime[j] > N / i) break;
fac[i * prime[j]] = prime[j];
}
}
}

####

标签:int,void,++,trs,mod,模板,rk
From: https://www.cnblogs.com/nangle/p/18391577

相关文章

  • 六大排序(算法详解+模板+例题)
    一.排序算法是什么排序算法(SortingAlgorithms)是一种数据结构操作,它的目的是将一串元素按照特定的顺序规则组织起来。常见的排序算法有升序(从小到大)和降序(从大到小)排列,如冒泡排序、希尔排序、插入排序、选择排序、快速排序、归并排序等。排序的主要目的是为了方便查找、分析数......
  • 白骑士的CSS高级篇之CSS Grid布局进阶 4.1.2 网格模板与区域
            CSSGrid布局是CSS中强大的布局系统之一,它提供了更灵活和更高效的方式来创建复杂的网页布局。通过Grid布局,你可以将网页划分为多个网格区域,并在这些区域中放置内容,这使得布局更加直观和易于维护。本文将深入探讨Grid布局中的网格模板和区域的概念,帮助你掌握如......
  • 用Python解决预测问题_对数线性模型模板
    对数线性模型(Log-linearmodel)是统计学中用于分析计数数据或频率数据的一类模型,特别是在多维列联表(contingencytables)分析中非常常见。这种模型通过取对数将乘法关系转换为加法关系,从而简化了数据分析。在对数线性模型中,我们通常对观测频数的对数进行建模,模型的形式可以表示......
  • Windows Server 2019 OVF, updated Aug 2024 (sysin) - VMware 虚拟机模板
    WindowsServer2019OVF,updatedAug2024(sysin)-VMware虚拟机模板2024年8月版本更新,现在自动运行sysprep,支持ESXiHostClient部署请访问原文链接:https://sysin.org/blog/windows-server-2019-ovf/,查看最新版。原创作品,转载请保留出处。现在都是自动sysprep的......
  • Android 读取 XML 文件之 SAX 解析编码模板
    一、SAX解析概述SAX(SimpleAPIforXML)是一种基于事件的XML解析技术,它一边读取XML文件一边解析,占用内存少,适用于大型文件SAX解析器会触发一系列事件,例如,开始解析元素、结束解析元素、遇到字符数据等,我们只需要实现对应的事件处理器来处理这些事件即可二、SAX......
  • WPF中如何根据数据类型使用不同的数据模板
    我们在将一个数据集合绑定到列表控件时,有时候想根据不同的数据类型,显示为不同的效果。例如将一个文件夹集合绑定到ListBox时,系统文件夹和普通文件夹分别显示为不同的效果,就可以使用模板选择器功能。WPF提供了一个模板选择器类型DataTemplateSelector,它可以根据数据对象和数据......
  • 设计模式之模板模式和策略模式-----------超级超级详细!超级全面!
    1.模板模式的定义一个抽象类,公开定义了执行自己的方法/模板。它的子类可以按需重写方法实现,但调用需要按照抽象类中的定义的方式/模板进行。这种类型的设计模式属于行为性模式之一。用于定义一个操作中的算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个......
  • 用模板30分钟完成人力资源网站,制作到上线的全流程
    疫情对线下企业的冲击非常大,2023年疫情基本结束,线下行业开始复苏,我们成立了自己的人力资源公司。由于企业刚起步,也没有太多的预算来进行网络方面的投入,但在疫情期间我们见识了互联网的重要性,因此计划给自己公司做一个简单的官网,这样可以让客户直接可以在百度搜到我们公司信息,......
  • Markdown通用模板
    要使用好AI工具,写好prompt(提示词)是非常重要的,提示词至少要有角色、上下文、任务。专家们提供了很多结构化提示词的框架,比如ICDO,BROKE,CRISP等,你知道哪些提示词框架?如果不知道,通过搜索工具或者AI工具学习一个。Markdown是结构化prompt的好方法,请为你学习的prompt框架使用Markdown......
  • 模板方法模式:如何实现同一模板框架下的算法扩展?
    模板方法模式的原理和代码实现都比较简单,在软件开发中也被广泛应用,但是因为使用继承机制,副作用往往盖过了主要作用,所以在使用时尤其要小心谨慎。一、模式原理分析模板方法模式原始定义是:在操作中定义算法的框架,将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的......