zoukankan      html  css  js  c++  java
  • [cf718E]Matvey's Birthday

    考虑$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 }
    View Code
  • 相关阅读:
    Compression algorithm (deflate)
    tcpip数据包编码解析(chunk and gzip)_space of Jialy_百度空间
    What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
    gzip压缩算法: gzip 所使用压缩算法的基本原理
    Decompressing a GZip Stream with Zlib
    Frequently Asked Questions about zlib
    how to decompress gzip stream with zlib
    自己动手写web服务器四(web服务器是如何通过压缩数据,web服务器的gzip模块的实现)
    What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
    C语言抓http gzip包并解压 失败 C/C++ ChinaUnix.net
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14820640.html
Copyright © 2011-2022 走看看