树上后缀数组

摘要:
=y){dfs(v,x);}}intlcp{intxx=x,yy=y;depifxx=bz[i][xx],yy=bz[i][yy];returnmin;//会有跳到根的情况}voidasa{intp=0;repc[i]=0;repc[x[i]=a[i]]++;repc[i]+=c[i-1];depsa[c[x[i]]--]=i;for{repxx[j]=x[bz[k][j]];repc[j]=0;repc[xx[j]]++;repc[j]+=c[j-1];depy[c[xx[j]]--]=j;//这里处理也要不同,因为按原先处理会有一些y相同repc[j]=0;repc[x[y[j]]]++;repc[j]+=c[j-1];depsa[c[x[y[j]]]--]=y[j];swap(x,y);x[sa[1]]=1;p=2;repx[sa[j]]=y[sa[j]]==y[sa[j-1]]&&y[bz[k][sa[j]]]==y[bz[k][sa[j-1]]]?

树上后缀数组模板题:

https://www.codechef.com/problems/DIFTRIP

树上后缀数组第1张树上后缀数组第2张
//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")

//#include <immintrin.h>
//#include <emmintrin.h>
#include <bits/stdc++.h>
using namespacestd;
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define IL inline
#define rint register intinline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
char ss[1<<24],*A=ss,*B=ss;
IL chargc()
{
    return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
}
template<class T>void maxa(T &x,T y)
{
    if (y>x) x=y;
}
template<class T>void mina(T &x,T y)
{
    if (y<x) x=y;
}
template<class T>void read(T &x)
{
    int f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
    while(c=gc(),c>47&&c<58) x=x*10+(c^48); x*=f;
}
const int mo=1e9+7;
ll fsp(int x,inty)
{
    if (y==1) returnx;
    ll ans=fsp(x,y/2);
    ans=ans*ans%mo;
    if (y%2==1) ans=ans*x%mo;
    returnans;
}
structcp {
    ll x,y;
    cp operator +(cp B)
    {
        return (cp){x+B.x,y+B.y};
    }
    cp operator -(cp B)
    {
        return (cp){x-B.x,y-B.y};
    }
    ll operator *(cp B)
    {
        return x*B.y-y*B.x;
    }
    int half() { return y < 0 || (y == 0 && x < 0); }
};
structre{
    inta,b,c;
};
#define ull unsigned long long
const int N=2e5;
const ull base=23333;
vector<int>ve[N];
ull ba[N],gg[20][N];
int bz[20][N],dep[N],a[N];
intx[N],y[N],sa[N],h[N],rk[N],c[N],xx[N],n;
void dfs(int x,inty)
{
    dep[x]=dep[y]+1; 
    bz[0][x]=y; gg[0][x]=a[x];
    rep(i,1,19) bz[i][x]=bz[i-1][bz[i-1][x]];
    rep(i,1,19) gg[i][x]=gg[i-1][x]+gg[i-1][bz[i-1][x]]*ba[(1<<(i-1))];
    for(auto v:ve[x])
      if (v!=y)
      {
          dfs(v,x);
      }
}
int lcp(int x,inty)
{
    int xx=x,yy=y;
    dep(i,19,0)
      if (gg[i][xx]==gg[i][yy])
        xx=bz[i][xx],yy=bz[i][yy];
    return min(dep[x]-dep[xx],dep[y]-dep[yy]); //会有跳到根的情况 
}
void asa(intn)
{
    int p=0;
    rep(i,1,n) c[i]=0;
    rep(i,1,n) c[x[i]=a[i]]++;
    rep(i,1,n) c[i]+=c[i-1];
    dep(i,n,1) sa[c[x[i]]--]=i;
    for (int i=1,k=0;i<=n;i<<=1,k++)
    {
        rep(j,1,n) xx[j]=x[bz[k][j]];
        rep(j,1,n) c[j]=0;
        rep(j,1,n) c[xx[j]]++;
        rep(j,1,n) c[j]+=c[j-1];
        dep(j,n,1) y[c[xx[j]]--]=j;
        
        //这里处理也要不同,因为按原先处理会有一些y相同 
        rep(j,1,n) c[j]=0;
        rep(j,1,n) c[x[y[j]]]++;
        rep(j,1,n) c[j]+=c[j-1];
        dep(j,n,1) sa[c[x[y[j]]]--]=y[j];
        swap(x,y); x[sa[1]]=1; p=2;
        rep(j,2,n)
          x[sa[j]]=y[sa[j]]==y[sa[j-1]]&&y[bz[k][sa[j]]]==y[bz[k][sa[j-1]]]?p-1:p++;
    }
    rep(i,1,n) rk[sa[i]]=i;
    rep(i,1,n)
    {
        h[i]=lcp(sa[i-1],sa[i]); //因为不满足h[rk[i]>=h[rk[i-1]]-1 所以只能倍增hash计算 
}
}
intmain()
{
   freopen("1.in","r",stdin);
   freopen("1.out","w",stdout);
   ios::sync_with_stdio(false);
   cin>>n;
   rep(i,1,n-1)
   {
        intx,y;
        cin>>x>>y;
        ve[x].push_back(y); ve[y].push_back(x);
   }
   rep(i,1,n) a[i]=ve[i].size();
   ba[0]=1;
   rep(i,1,n) ba[i]=ba[i-1]*base;
   dfs(1,0);
   asa(n);
   ll ans=0;
       for(int i=1;i<=n;i++) 
        ans+=dep[sa[i]]-h[i];
    cout<<ans<<endl; 
   return 0;
}
View Code

免责声明:文章转载自《树上后缀数组》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux下安装zabbix服务器42岁大龄程序员的迷茫,看我最新尝鲜.net 5+Dapper搭建的WebAPI框架下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

通俗易懂的KMP算法详解

角色: 甲:abbaabbaaba 乙:abbaaba 乙对甲说:「帮忙找一下我在你的哪个位置。」 甲从头开始与乙一一比较,发现第 7 个字符不匹配。 要是在往常,甲会回退到自己的第 2 个字符,乙则回退到自己的开头,然后两人开始重新比较。[1]这样的事情在字符串王国中每天都在上演:不匹配,回退,不匹配,回退,…… 但总有一些妖艳字符串要花出自己不少的...