考虑$i$到$j$的最短路,记作$dis(i,j)$,令字符集大小为$T=8$,有$dis(i,j)<2T$
证明:
记$l=dis(i,j)$,假设这条最短路依次经过$a_{0},a_{1},...,a_{l}$(其中$a_{0}=i,a_{l}=j$)
若存在$0le i<j<kle l$,满足$s_{a_{i}}=s_{a_{j}}=s_{a_{k}}$,显然此时直接从$a_{i}$到$a_{k}$更短
即每一种字符最多出现两次,根据抽屉原理,即有$l<2T$
更进一步的,对其分两类讨论:
1.没有使用第2类边,那么显然是$|i-j|$
2.使用了第2类边,假设是这条边是$(a,b)$,则$dis(i,j)=min_{(a,b)}dis(i,a)+dis(b,j)+1$
考虑先枚举$s_{a}=s_{b}=c$,此时不难发现$a$和$b$独立,即可以对$a$和$b$分别取$dis(i,a)$和$dis(b,j)$最小
更具体的,记$f_{i,c}=min_{s_{j}=c}dis(i,j)$,即$dis(i,j)=min_{c}f_{i,c}+f_{j,c}+1$
综上,即
$$
dis(i,j)=min(|i-j|,min_{c}f_{i,c}+f_{j,c}+1)
$$
关于如何计算$f_{i,c}$,枚举$c$并从该种字符的位置出发进行bfs,第2类边显然仅允许第一次搜到该颜色时走,因此单次复杂度为$(n)$,总复杂度为$o(nT)$
此时,考虑暴力从大到小枚举直径$din [1,2T)$,并求出最短路大于等于$d$的点对数,若不为0则此时的$d$以及求出的点对数即为答案
考虑如何求最短路大于等于$d$的点对数,即$|i-j|ge d$且$min_{c}f_{i,c}+f_{j,c}+1ge d$的$(i,j)$对数
先考虑第二个条件,即$min_{c}f_{i,c}+f_{j,c}+1ge d$
构造$g_{c_{1},c_{2}}=min_{s_{i}=c_{1}}f_{i,c_{2}}$,显然可以$o(nT)$计算,同时有以下性质:$g_{s_{i},c}le f_{i,c}le g_{s_{i},c}+1$
左半部分是根据$g_{c_{1},c_{2}}$的定义,在求$min$时取$i$即可
右半部分考虑$f_{i,c}$第一次直接从$i$开始走第2类边,即为$g_{s_{i},c}+1$
由此,将$f_{i,c}-g_{s_{i},c}$看作二进制上的某一位,即压成了一个$2^{T}$的二进制数
对于每一个$i$,令这个二进制数为$state_{i}$,则通过$(s_{i},state_{i})$即可确定所有$f_{i,c}$,进而也可以确定判定结果,那么不妨去枚举$(s_{i},state_{i})$,再预处理其数量即可
统计出每一个状态的数量,并对每两个状态都求出$min_{c}f_{i,c}+f_{j,c}+1$(因为$d$会变化),由于预处理时$d$不变化,$d$变化时通过预处理可以$o(1)$,复杂度为$o(nT+T^{3}2^{2T})$($o(nT)$是统计数量)
再对第一个条件容斥,即减去$min_{c}f_{i,c}+f_{j,c}+1ge d$且$|i-j|<d$的$(i,j)$对数
直接$o(nT)$枚举$i$和$j$,通过前面的预处理可以$o(1)$判定前者,复杂度为$o(nT^{2})$(对每一个$d$都要做一次)
将两者的答案累加即可,最终总复杂度为$o(nT^{2}+T^{3}2^{2T})$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define T 8 5 #define L 15 6 queue<int>q; 7 vector<int>v[T]; 8 int n,a[N],vis[N],visc[T],f[N][T],g[T][T],state[N],tot[T][1<<T],d[T][1<<T][T][1<<T]; 9 char s[N]; 10 int main(){ 11 scanf("%d%s",&n,s+1); 12 for(int i=1;i<=n;i++)a[i]=s[i]-'a'; 13 for(int i=1;i<=n;i++)v[a[i]].push_back(i); 14 for(int i=0;i<T;i++){ 15 if (!v[i].size()){ 16 for(int j=1;j<=n;j++)f[j][i]=0x3f3f3f3f; 17 continue; 18 } 19 memset(vis,0,sizeof(vis)); 20 memset(visc,0,sizeof(visc)); 21 for(int j=0;j<v[i].size();j++){ 22 q.push(v[i][j]); 23 vis[v[i][j]]=1; 24 } 25 while (!q.empty()){ 26 int k=q.front(); 27 q.pop(); 28 if ((k>1)&&(!vis[k-1])){ 29 f[k-1][i]=f[k][i]+1; 30 q.push(k-1); 31 vis[k-1]=1; 32 } 33 if ((k<n)&&(!vis[k+1])){ 34 f[k+1][i]=f[k][i]+1; 35 q.push(k+1); 36 vis[k+1]=1; 37 } 38 if (!visc[a[k]]){ 39 for(int j=0;j<v[a[k]].size();j++) 40 if (!vis[v[a[k]][j]]){ 41 f[v[a[k]][j]][i]=f[k][i]+1; 42 q.push(v[a[k]][j]); 43 vis[v[a[k]][j]]=1; 44 } 45 visc[a[k]]=1; 46 } 47 } 48 } 49 memset(g,0x3f,sizeof(g)); 50 for(int i=0;i<T;i++) 51 for(int j=0;j<T;j++) 52 for(int k=0;k<v[j].size();k++)g[j][i]=min(g[j][i],f[v[j][k]][i]); 53 for(int i=1;i<=n;i++){ 54 for(int j=T-1;j>=0;j--)state[i]=(state[i]<<1)+(f[i][j]-g[a[i]][j]); 55 tot[a[i]][state[i]]++; 56 } 57 for(int i1=0;i1<T;i1++) 58 for(int j1=0;j1<(1<<T);j1++) 59 for(int i2=0;i2<T;i2++) 60 for(int j2=0;j2<(1<<T);j2++){ 61 d[i1][j1][i2][j2]=0x3f3f3f3f; 62 for(int i=0;i<T;i++){ 63 int x=g[i1][i]+((j1&(1<<i))>0),y=g[i2][i]+((j2&(1<<i))>0); 64 d[i1][j1][i2][j2]=min(d[i1][j1][i2][j2],x+y+1); 65 } 66 } 67 for(int i=L;i;i--){ 68 long long ans=0; 69 for(int i1=0;i1<T;i1++) 70 for(int j1=0;j1<(1<<T);j1++) 71 for(int i2=0;i2<T;i2++) 72 for(int j2=0;j2<(1<<T);j2++) 73 if (d[i1][j1][i2][j2]>=i)ans+=1LL*tot[i1][j1]*tot[i2][j2]; 74 for(int j=1;j<=n;j++) 75 for(int k=max(j-i+1,1);k<=min(j+i-1,n);k++) 76 if (d[a[j]][state[j]][a[k]][state[k]]>=i)ans--; 77 if (ans){ 78 printf("%d %lld",i,ans/2); 79 return 0; 80 } 81 } 82 }