题目大意

给定一个长度为n的字符串,字符集大小为8。两个点i,j之间有权值为1的边当且仅当满足以下条件之一
1. |i-j|=1
2. si=sj

求图的直径和多少个有序点对之间的最短路长度等于直径

2≤n≤100000

分析

好题
设dist(i,j)dist(i,j)表示点i到点j的最短距离,Dist(i,c)Dist(i,c)表示点i到字符c的最短距离。
易得dist(i,j)=min(|i−j|,Dist(i,c)+Dist(j,c)+1)dist(i,j)=min ( |i-j|,Dist(i,c)+Dist(j,c)+1 )
由于字符集大小为8,观察上式,容易证明最短路长度不超过15。于是对于|i−j|>15|i-j|>15的点对,我们发现dist(i,j)=min(Dist(i,c)+Dist(j,c)+1)dist(i,j)=min(Dist(i,c)+Dist(j,c)+1)

首先我们可以枚举c,然后通过bfs得到数组Dist[][c]Dist[][c]。
接下来设D(p,q)D(p,q)表示字符p到字符q的最短距离,易得对于任意i,有D(si,c)≤Dist(i,c)≤D(si,c)+1D(si,c)≤Dist(i,c)≤D(si,c)+1

那么再设Mask(i)Mask(i),这是个二进制状态,第c位表示Dist(i,c)−D(si,c)Dist(i,c)-D(si,c)
那么Dist(i,c)+Dist(j,c)+1=Dist(i,c)+D(sj,c)+Mask(j)c+1Dist(i,c)+Dist(j,c)+1=Dist(i,c)+D(sj,c)+Mask(j)_c+1
我们在计算|i−j|>15|i-j|>15的答案时,枚举i,同时维护一个数组f[c][mask]f[c][mask],表示字符是c,Mask是mask的位置j有多少个。然后可以枚举c和mask并计算距离。
|i−j|≤15|i-j|≤15的点对直接枚举即可

时间复杂度O(n∗82∗28)O(n*8^2*2^{8})

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))using namespace std;const int N=1e5+30,M=256,C=8,mx=15,INF=1e8;typedef long long LL;int n,Dist[N][C],D[C][C],Mask[N],f[C][M],ans,Data[N],tot;LL sum;char S[N];void bfs(int c)
{Data[tot=1]=n+c; Dist[n+c][c]=-1;for (int i=1,j,x;i<=tot;i++){x=Data[i];if (x<n){if (x>0 && Dist[x-1][c]>INF){Dist[x-1][c]=Dist[x][c]+1; Data[++tot]=x-1;if (Dist[S[x-1]+n][c]>INF){Dist[S[x-1]+n][c]=Dist[x][c]+1; Data[++tot]=S[x-1]+n;}}if (x<n-1 && Dist[x+1][c]>INF){Dist[x+1][c]=Dist[x][c]+1; Data[++tot]=x+1;if (Dist[S[x+1]+n][c]>INF){Dist[S[x+1]+n][c]=Dist[x][c]+1; Data[++tot]=S[x+1]+n;}}}else{for (j=0;j<n;j++) if (S[j]+n==x && Dist[j][c]>INF){Dist[j][c]=Dist[x][c]+1; Data[++tot]=j;}}}
}int main()
{scanf("%d%s",&n,S);for (int i=0;i<n;i++) S[i]-='a';memset(Dist,42,sizeof(Dist));memset(D,42,sizeof(D));for (int i=0;i<C;i++) bfs(i);for (int i=0;i<n;i++) for (int j=0;j<C;j++) D[S[i]][j]=min(D[S[i]][j],Dist[i][j]);for (int i=0;i<n;i++) for (int j=C-1;j>=0;j--) Mask[i]=(Mask[i]<<1)|Dist[i][j]-D[S[i]][j];for (int i=mx;i<n;i++) f[S[i]][Mask[i]]++;for (int i=0,dist;i<n;i++){if (i+mx<n) f[S[i+mx]][Mask[i+mx]]--;for (int c=0;c<C;c++){for (int mask=M-1;mask>=0;mask--) if (f[c][mask]>0){dist=mx;for (int c_=0;c_<C;c_++) dist=min(dist,Dist[i][c_]+D[c][c_]+((mask&(1<<c_))>0)+1);if (dist>ans) ans=dist,sum=0;if (dist==ans) sum+=f[c][mask];}}if (i>=mx) f[S[i-mx]][Mask[i-mx]]++;for (int j=max(0,i-mx);j<=min(n-1,i+mx);j++){dist=abs(i-j);for (int c_=0;c_<C;c_++) dist=min(dist,Dist[i][c_]+Dist[j][c_]+1);if (dist>ans) ans=dist,sum=0;if (dist==ans) sum++;}}printf("%d %lld\n",ans,sum>>1);return 0;
}

[codeforces 718E]Matvey's Birthday相关推荐

  1. codeforces 718E. Matvey's Birthday

    题目链接:http://codeforces.com/contest/718/problem/E 题目大意:给定一个长度为n的只包含a~h的字符串s,对于1<=a,b<=n,,如果|a-b ...

  2. Codeforces 718E.Matvey's Birthday dp+状态压缩

    题意 给定一个长度为n的字符串,字符集大小为8.两个点i,j之间有权值为1的边需要满足以下条件至少一个 1. |i-j|=1 2. si=sj 求图的直径和多少个有序点对之间的最短路长度等于直径 N≤ ...

  3. Codeforces 718E Matvey's Birthday bfs

    题意 给一个长度为n的字符串s,字符集大小为m. 再建立一张n个点的图,其中串中第i个字符就对应图中第i个点. 对这张图连这样两种边: 若对于i,j,满足|i-j|<=1,在点i和点j之间连双向 ...

  4. 【CodeForces】【BFS】【状压】718E Matvey's Birthday

    CodeForces 718E Matvey's Birthday 题目大意 ◇题目传送门◆ 今天与 CF 的连接怎么这么稳定??? 给定一个长度为NNN的字符串sss,字符集为小写字母aaa到hhh ...

  5. 【codeforces 718E】E. Matvey's Birthday

    题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含'a'~'h'8个字符的字符串 ...

  6. [Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday

    题意 给定一个字符串,字符集大小为8 将每个位置当做一个点,相邻位置有长度为1的连边,任意相同字母的位置之间有长度为1的连边.求图的直径和直径的长度. n≤105n\le 10^5 题解 求图的直径需 ...

  7. CodeForces 375D Tree and Queries

    传送门:https://codeforces.com/problemset/problem/375/D 题意: 给你一颗有根树,树上每个节点都有其对应的颜色,有m次询问,每次问你以点v为父节点的子树内 ...

  8. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

  9. 【codeforces 812C】Sagheer and Nubian Market

    [题目链接]:http://codeforces.com/contest/812/problem/C [题意] 给你n个物品; 你可以选购k个物品;则 每个物品有一个基础价值; 然后还有一个附加价值; ...

最新文章

  1. 在CentOS 6.3 64bit上安装ATS 5.3 LTS版本并测试
  2. 如何获取有性能问题的SQL
  3. Oracle 11g dataguard主库坏块修复
  4. js中==与===的区别
  5. aspnetcore 实现简单的伪静态化
  6. linux的软件很大,linux软件raid10,机器相同,结果差异很大
  7. 抄底王牌tdx 副图(无未來函数)
  8. maya多象限uv不显示_CG制作软件这么多,你都会哪些?
  9. c++ -- 重载、重写(覆盖)和隐藏的区别
  10. Java WEB之过滤器
  11. 一个简易的选择小时(时分秒)的插件
  12. 【BZOJ4554】游戏(二分图匹配,网络流)
  13. 获取对象属性名的方法 Object.keys() 与 Object.getOwnPropertyNames() 与 for循环
  14. window.print()
  15. Win 7 安装office visio
  16. shadow密码字段为!!_您的密码可能不如您想像的安全!
  17. 说说财务系统中的月末结账功能
  18. python随机出100道加法题_python3 随机生成10以内的加法算术题
  19. 【贪心法】黑白连线问题
  20. 【经验】不摸鱼的时光

热门文章

  1. oracle数据库有触发器,Oracle数据库触发器(Triggers)
  2. java开发人员macOS系统上需要安装软件以及常用快捷键
  3. BSN应用案例精选【1】:全链通“铭镜”农产品溯源平台
  4. 信息安全系统设计基础实验一—20135222胡御风20135215黄伟业
  5. ker矩阵是什么意思_直观理解!你一定要读一下的“矩阵和线性代数入门”
  6. 使用CSS中clip-path属性实现奥运五环
  7. WebDAV将会在公共领域取代FTP
  8. 重磅推荐 | SkyWalking未来初探(文末有福利哦)
  9. android智能电灯,X-Light智能灯泡
  10. 微分几何笔记(2):微分流形的例子