【codeforces 718E】E. Matvey's Birthday
题目大意&链接:
http://codeforces.com/problemset/problem/718/E
给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s。两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j]。求这个无向图的直径,以及直径数量。
题解:
命题1:任意位置之间距离不会大于15。
证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多为15。
然后我们对于每个节点,需要计算出其与其他节点距离,当然为了不重复,只需考虑pos小于当前节点的位置。此时我们分为两种情况:
1.|i-j|<=15;
2.|i-j|>15。
对于第一种我们是取|i-j|与i先到达一种字母,j也到达这种字母距离和取较小值。所以我们设
$F[i][c]$表示i节点到达c这种字母的最小距离。即i到j的距离为:$min(|i-j|,F[i][c]+1+F[j][c])$。
命题2:i与j到达的同一种字母的位置如果相同,一定不是最优解。
证明:假设到达同一个位置,那么只可能是通过这个位置的左右两个节点。那么,对于到达左右这两个节点如果其路径之间不存在相同的字母,那么其距离和|i-j|相同,如果存在相同字母,则一定比当前方式短。综上所述,到达同一位置一定不是最短路。
对于第二种,我们由命题1可知,其距离不会大于15。我们再来看一个命题:
命题3:设$dis[c1][c2]$表示c1字母到达c2字母的最小距离,那么我们有,若$s[i]==c1$,则$dis[c1][c2]<=F[i][c2]<=dis[c1][c2]+1$。
证明:这个……显然吧?
我们此时考虑对于第二种情况下的j,|i-j|一定不是最短的,所以一定是从$F[i][c]+1+F[j][c]$中选取最小值,那么由命题3可知,我们并不需要其确切位置,仅需知道$F[i][c]$与$dis[ci][c]$之间的关系,然后我们可以用一个二进制数$mark[j]$来表示其与$dis[cj][c]$之间的关系,然后我们把关系相同(即mark[j]相同)的j统计其数量,然后再求一下此时i与某一种mark之间的最短路即可。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=;
int n,f[N][],dis[][];
char s[N];
int q[N],d[N];
int mark[N];
int c[N][<<];
inline void bfs(int c){
int l=,r=;
for(int i=;i<=n;i++)if(s[i]-'a'==c){
q[r++]=i,d[i]=;
}else d[i]=-;
bool vis[]={};
vis[c]=true;
while(l<r){
int now=q[l++];
if(!vis[s[now]-'a']){
vis[s[now]-'a']=true;
for(int i=;i<=n;i++)
if(s[i]==s[now]&&d[i]==-){
d[i]=d[now]+;
q[r++]=i;
}
}
if(now>&&d[now-]==-) q[r++]=now-,d[now-]=d[now]+;
if(now<n&&d[now+]==-) q[r++]=now+,d[now+]=d[now]+;
}
for(int i=;i<=n;i++)
if(d[i]!=-)f[i][c]=d[i];
}
int main(){
// freopen("1.out","w",stdout);
scanf("%d",&n);
scanf("%s",s+);
memset(f,0x3f,sizeof(f));
for(int i=;i<;i++)
bfs(i);
memset(dis,0x3f,sizeof(dis));
for(int i=;i<=n;i++)
for(int j=;j<;j++)
dis[s[i]-'a'][j]=min(dis[s[i]-'a'][j],f[i][j]);
for(int i=;i<=n;i++) for(int j=;j<;j++)
if(f[i][j]>dis[s[i]-'a'][j]) mark[i]|=<<j;
// for(int i=1;i<=n;i++)
// printf("mark[%d]=%d\n",i,mark[i]);
int ans=;
long long cnt=;
for(int i=;i<=n;i++){
for(int j=max(i-,);j<i;j++){
int now=i-j;
for(int k=;k<;k++)
now=min(now,f[j][k]++f[i][k]);
if(now==ans) cnt++;
if(now>ans) ans=now,cnt=;
}
int t=i-;
if(t>=) c[s[t]-'a'][mark[t]]++;
for(int j=;j<;j++) for(int k=;k<;k++)
if(c[j][k]){
int now=0x7fffffff;
for(int l=;l<;l++){
now=min(now,dis[j][l]++f[i][l]+((k&(<<l))>>l));
//printf("%d\n",(k&(1<<l))>>l);
}
if(now==ans) cnt+=c[j][k];
if(now>ans) ans=now,cnt=c[j][k];
}
}
printf("%d %lld\n",ans,cnt);
}
【codeforces 718E】E. Matvey's Birthday的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
- 【Codeforces 670C】 Cinema
[题目链接] http://codeforces.com/contest/670/problem/C [算法] 离散化 [代码] #include<bits/stdc++.h> using ...
- 【codeforces 515D】Drazil and Tiles
[题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...
随机推荐
- spring-cloud-config安全问题
配置服务的安全问题会很重要,其中的内容是我自己学习的,由于学习时间不长,有可能不是很完备,如果有更好的方案,烦请评论中留言或私信,谢谢! 1. 首先访问配置服务需要设置密码: 使用spring-sec ...
- uwsgi 服务 invalid request block size: 4161 (max 4096)...skip问题的解决
问题报错: invalid request block size: 4161 (max 4096)...skip 问题原因:默认的uwsgi分配一个小的buffer(4k)来接收每个请求的头信息,如果 ...
- 面试(三)---volatile
一.前言 最近去成都玩了一圈,整体感觉还不错,辞职以后工作找的也很顺利,随着年龄增加自己也考虑定居和个人长期发展的问题,反正乱七八糟的事,总之需要好好屡屡思路,不能那么着急下定论,当然我对 ...
- C# 获取文件下载的各种方法
public class RemoteDownload { public static void DownLoad(string addressUrl,string localName) { //下载 ...
- C#学习笔记 day_two
C#学习笔记 day two Chapter 2 c#基本概念 2.1编译与运行hello world应用程序 点击f5或者vs2010中的运行图标即可 2.3C#的概念拓展 (1)继承性:一个类含有 ...
- Install and Configure Apache Kafka on Ubuntu 16.04
https://devops.profitbricks.com/tutorials/install-and-configure-apache-kafka-on-ubuntu-1604-1/ by hi ...
- Python 基础【二】 上
一.python语言分类 1. C python c语言的python版本 官方推荐 使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行 ...
- .net自定义错误页面实现升级篇
问题描述: 在上一篇博文 ".net自定义错误页面实现" 中已经介绍了在.net中如何实现自定义错误页面实现(有需要者可以去上一篇博文了解),单纯按照上一篇博文那样设置,能够实现所 ...
- Masonry 抗压缩 抗拉伸
约束优先级: 在Autolayout中每个约束都有一个优先级, 优先级的范围是1 ~ 1000.创建一个约束,默认的优先级是最高的1000 Content Hugging Priority: 该优先级 ...
- 什么是web service ?
一.序言 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成分.但是不得不承认的是Web ...