题意

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

题解

求图的直径需要求任意两点间的最短路,这是不现实的。

设DIS(i,j)DIS(i,j)为位置ii与位置jj之间的最短路,那么

DIS(i,j)=min{|i−j|,min{dis(i,c)+1+dis(j,c)}}

DIS(i,j) = min\{|i-j|,min\{dis(i,c)+1+dis(j,c)\}\}
其中 dis(i,c)dis(i,c)表示从某个位置到达字符 xx的最短距离。

为什么dis(i,c)+1+dis(j,c)dis(i,c)+1+dis(j,c)里面要 +1+1呢?因为如果 i,ji,j都到达了同一个 cc,那么这个长度一定大于等于|i−j||i-j|。

同时我们能得到这样的结论,树的直径小于字符集大小的二倍,即15,这个串就是一个例子aabbccddeeffgghh

枚举ii,同时枚举jj

  1. |i−j|<16|i-j|,此时直接由DIS(i,j)=min{|i−j|,min{dis(i,c)+1+dis(j,c)}}DIS(i,j) = min\{|i-j|,min\{dis(i,c)+1+dis(j,c)\}\}求出
  2. |i−j|≥16|i-j|\ge 16,不能直接枚举jj了,此时DIS(i,j)=min{dis(i,c)+1+dis(j,c)}DIS(i,j)=min\{dis(i,c)+1+dis(j,c)\}

现在设法求出|i−j|≥16|i-j|\ge 16时的max{DIS(i,j)}max\{DIS(i,j)\},注意此时的ii是固定的,jj是不确定的。

再设d(c1,c2)d(c_1,c_2)代表字符c1c_1与c2c_2之间的最短距离。那么d(sj,c)≤dis(j,c)≤d(sj,c)+1d(s_j,c)\le dis(j,c)\le d(s_j,c)+1,也就是要么sjs_j与cc之间最短路恰好是jj位置到cc的最短路,要么需要再跳一步。

预处理求出disdis数组与dd数组,再设一个maskmask数组,mask(j)mask(j)对于每一个位置jj,用二进制存下dis(j,c)−d(sj,c),0≤c<8dis(j,c)-d(s_j,c), 0\le c
再设数组cnt(x,mask)cnt(x,mask)来统计j(|i−j|≥16),sj=x且mask(j)=maskj (|i-j|\ge16) , s_j=x 且 mask(j) = mask的数量。

ii确定时先确定sjs_j再枚举maskmask,此时

min{dis(i,c)+1+dis(j,c)}=min{dis(i,c)+1+d(sj,c)+maskc}

min\{dis(i,c)+1+dis(j,c)\} =min\{ dis(i,c)+1+d(s_j,c)+mask_{c}\}
这样就能求出 i,sj,maski,s_j,mask确定时的最短路并更新答案。
时间复杂度 O(n⋅|C|3+n⋅|C|2⋅2|C|)O(n\cdot |C|^3+n\cdot |C|^2\cdot 2^{|C|}),其中 |C||C|为字符集大小。

代码

/// by ztx
/// blog.csdn.net/hzoi_ztx#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define rep(i,l,r) for(i=(l);i< (r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
#define rev(i,r,l) for(i=(r);i> (l);i--)
#define Each(i,v)  for(i=v.begin();i!=v.end();i++)
#define r(x)   read(x)
typedef long long ll ;
typedef double lf ;
int CH , NEG ;
template <typename TP>inline void read(TP& ret) {ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;if (CH == '-') NEG = true , CH = getchar() ;while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;if (NEG) ret = -ret ;
}#define  maxn  100010LL
#define  infi  0x3f3f3f3fLL#define  id(c) (c+n+1)
int n, ans;
ll cnt;
int dis[maxn][8], d[8][8], mask[maxn],c[8][256];
char s[maxn];
std::queue<int> q;
inline void bfs(int x) {int i, u, v;dis[id(x)][x] = 0;Rep (i,1,n) if (s[i] == x)dis[i][x] = 0, q.push(i);while (!q.empty())if (u = q.front(), q.pop(), u <= n) {if (v = u+1, 1<=v && v<=n && dis[v][x]==infi) {dis[v][x] = dis[u][x]+1, q.push(v);if (dis[id(s[v])][x] == infi)dis[id(s[v])][x] = dis[u][x]+1, q.push(id(s[v]));}if (v = u-1, 1<=v && v<=n && dis[v][x]==infi) {dis[v][x] = dis[u][x]+1, q.push(v);if (dis[id(s[v])][x] == infi)dis[id(s[v])][x] = dis[u][x]+1, q.push(id(s[v]));}}else Rep (i,1,n) if (id(s[i])==u && dis[i][x]==infi)dis[i][x] = dis[u][x]+1, q.push(i);
}int main() {int i, j, k, l, now, x;r(n), scanf("%s", s+1);Rep (i,1,n) s[i] -= 'a';memset(dis, 0x3f, sizeof dis);while (!q.empty()) q.pop();rep (i,0,8) {bfs(i);rep (x,0,8) d[x][i] = dis[id(x)][i];}Rep (i,1,n) rep (x,0,8)if (dis[i][x] > d[s[i]][x]) mask[i] |= 1<<x;Rep (i,1,n) {rep (j,std::max(i-15,1),i) {now = i-j;rep (k,0,8) now = std::min(now, dis[j][k]+dis[i][k]+1);if (now == ans) cnt ++ ;if (now > ans) ans = now, cnt = 1;}int t = i-16;if (t >= 1) c[s[t]][mask[t]] ++ ;rep (x,0,8) rep (k,0,256)if (c[x][k]) {now = infi;rep (l,0,8) now = std::min(now, d[x][l]+1+dis[i][l]+(k&(1<<l)));if (now == ans) cnt += c[x][k];if (now > ans) ans = now, cnt = c[x][k];}}printf("%d %lld\n", ans, cnt);END: getchar(), getchar();return 0;
}

[Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday相关推荐

  1. Codeforces Round #797 (Div. 3)无F

    Codeforces Round #797 (Div. 3)无F 这打的也太屎了,白天把G补了才知道简单的很,但f还是没头绪呜呜呜 Problem - A - Codeforces Given the ...

  2. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  3. Codeforces Round #417:E. FountainsSagheer and Apple Tree(树上博弈)

    Codeforces Round #417:E. FountainsSagheer and Apple Tree(树上博弈) 标签: codeforces 2017-06-02 11:41 29人阅读 ...

  4. Codeforces Round #563 (Div. 2)/CF1174

    Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...

  5. Codeforces Round #270

    Codeforces Round #270 题目链接 A:我是筛了下素数.事实上偶数仅仅要输出4和x - 4,奇数输出9和x - 9就可以 B:贪心的策略,把时间排序后.取每k个的位置 C:贪心.每次 ...

  6. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  7. [Educational Codeforces Round 16]A. King Moves

    [Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...

  8. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  9. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

最新文章

  1. 《20170914-构建之法:现代软件工程-阅读笔记》
  2. 【leetcode】力扣刷题(3):无重复字符的最长子串(go语言)
  3. R语言笔记1:数据类型(向量、数组、矩阵、 列表和数据框)
  4. 共谋大数据产业发展新篇章
  5. 3.放弃CHAR吧,在铸成大错之前!
  6. 【CCFCSP - 201403-4】无线网络(分层图最短路)
  7. 下载丨2020 PG亚洲大会(PPT汇总)
  8. (131)FPGA面试题-用波形图表示D触发器的功能
  9. centos 6.4 更新源地址
  10. linux中的rootfs/initrd/ramfs/initramfs
  11. EPM连接显示服务器不可用,EPM问题汇总之-SmartView没法链接Essbase
  12. java安装包_Java6 Update
  13. instantclient oracle oci
  14. 测试晶面间距软件_i-TEM软件测量TEM高分辨像晶面间距.PDF
  15. C++中char类型详解
  16. python实现自动化查谁没交作业
  17. 第 7 章网络可扩展性
  18. 北航计算机学院的博士待遇,北航博士毕业留校让人寒心的工资
  19. Linux的使用和命令的集合
  20. 基于stm32的DHT11、光照强度、烟雾浓度、振动频率的proteus仿真(全网第一)

热门文章

  1. Intel汇编-传送MMX整数
  2. STM32在线升级OTA,看这一篇就够啦~
  3. 机器人中的坐标转换关系(个人记录学习)
  4. 修复Linux 的GRUB引导文件
  5. 复杂网络中节点重要性方面的研究热点问题
  6. unity3d 怎么生成网页版_Unity3D 基础教程3D网页游戏场景打包与加载
  7. 【科创人】悦跑圈CTO钱荣明:创业成瘾,识人为先
  8. Linux 驱动 | SPI子系统
  9. 如何看计算机cpu的好坏,怎么看电脑的配置(如何判断cpu的好坏)
  10. Jia This 学习