Codeforces 题面传送门 & 洛谷题面传送门

首先注意到这个图的特殊性:我们对于所有 \(s_i=s_j\)​ 的 \((i,j)\)​ 之间都连了条边,而字符集大小顶多只有 \(8\)​,因此当 \(n\)​ 比较大时这张图肯定是相当稠密的,故我们猜测这个直径长度肯定也不会太长。事实的确如此,具体来说,对于图上任意两个点 \(i,j\)​,它们之间最短距离的长度肯定不会超过 \(15\)​,具体证明大概就对于每一对字母 \((x,y)\)​,如果存在某两个位置 \(i,i+1\) 满足 \(s_i=x,s_{i+1}=y\) 那么我们就在 \(x,y\) 之间连一条无向边。那么显然得到的大小为 \(s\text{中出现过的字符个数}\) 的图是连通图,故 \(\forall i,j\),\(s_i,s_j\) 在图上的距离不会超过 \(7\),而对于图上的一个大点(也就是每一种字母缩成的一个点),其包含的所有小点两两之间的最短距离恰好为 \(1\),也就是说,对于我们缩点后形成的图,我们假设我们找到了一条路径 \(v_1\to v_2\to\cdots\to v_k\),那么我们最多只用花 \(1\) 的代价实现从 \(v_{k-1}\to v_k\) 这条边到达 \(v_k\to v_{k+1}\) 这条边。因此这个最短距离的上界就是 \(8+7=15\)。

接下来我们考虑探究一下两点 \(i,j\) 之间的最短路是什么。不妨假设 \(i<j\),那么从 \(i\) 到达 \(j\) 有两种选择,要么一直往右走,步数 \(j-i\),要么经过某条连接两个不相邻的点的边,而这可以视作,选择某种字符 \(c\),然后从 \(i\) 走到某个字符为 \(c\) 的点,然后 \(j\) 也走到某个字符为 \(c\) 的点,然后再花费 \(1\) 的代价连接这两个字符为 \(c\) 的点,那么我们记 \(dis_{i,c}\) 表示 \(i\) 到达字符为 \(c\) 的点的最小代价。\(dis_{i,c}\) 可以通过用建虚点的技巧,也就是对于每个字符建一个虚点,然后对于所有字符为 \(c\) 的点,连一条该点到该字符对应的虚点,权值为 \(1\) 的边以及该字符对应的虚点到该点,权值为 \(0\) 的边,再使用多源 01bfs 在 \(\mathcal O(8n)\) 的时间内求出。这样我们即可在 \(\mathcal O(1)\) 的时间内计算两个点的最短距离,即 \(dis(i,j)=\min(j-i,dis_{j,k}+dis_{i,k}+1)\),这样暴力枚举是平方的,不过注意到一个性质,就是如果 \(j-i>15\),那么显然这个 \(\min\) 会取到后者,因此对于 \(j-i\le 15\) 我们考虑暴力枚举,\(j-i>15\) 的情况,注意到如果我们设 \(disc_{c1,c2}\) 为所有 \(s_i=c1\) 的点中 \(dis_{i,c2}\) 的最小值,那么必然有 \(dis_{i,c}-disc_{s_i,c}\in\{0,1\}\)。因此我们考虑在枚举的过程中将这个状态用一个 \(8\) 位二进制数记录下来,具体来说我们对于每个 \(i\) 记录一个 \(8\) 位二进制数 \(S\),\(S\) 的第 \(c\) 位为 \(1\) 表示 \(dis_{i,c}-disc_{s_i,c}=1\),否则 \(dis_{i,c}-disc_{s_i,c}=0\),然后我们在枚举的过程中开一个桶 \(cnt_{j,S}\) 表示前面有多少个 \(s_i=j\) 且 \(j\) 的状态为 \(S\),然后对于前面的答案就暴力对所有 \(j,S\) 批量处理答案即可。

时间复杂度 \(\mathcal O(8192·n)\),由于完全卡不满,可以通过此题。

const int MAXN=1e5;
const int MAXP=256;
const int INF=1061109567;
int n,cnt[MAXP+2][9];char s[MAXN+5];
int dis[MAXN+15][9],disc[9][9],res=0;ll resc=0;
void merge(int x,int y){
// printf("%d %d\n",x,y);
if(x>res) res=x,resc=y;
else if(x==res) resc+=y;
}
int main(){
scanf("%d%s",&n,s+1);
memset(dis,63,sizeof(dis));memset(disc,63,sizeof(disc));
for(int i=0;i<8;i++){
deque<int> q;
for(int j=1;j<=n;j++) if(s[j]-'a'==i) dis[j][i]=0,q.push_back(j);
while(!q.empty()){
int x=q.front();q.pop_front();
if(x<=n){
if(x-1>=1&&dis[x-1][i]==INF) dis[x-1][i]=dis[x][i]+1,q.push_back(x-1);
if(x+1<=n&&dis[x+1][i]==INF) dis[x+1][i]=dis[x][i]+1,q.push_back(x+1);
if(dis[s[x]-'a'+n+1][i]==INF) dis[s[x]-'a'+n+1][i]=dis[x][i]+1,q.push_back(s[x]-'a'+n+1);
} else {
for(int j=1;j<=n;j++) if(s[j]-'a'==x-n-1)
if(dis[j][i]>=dis[x][i]) dis[j][i]=dis[x][i],q.push_front(j);
}
} for(int j=1;j<=n;j++) chkmin(disc[s[j]-'a'][i],dis[j][i]);
// for(int j=1;j<=n;j++) printf("%d%c",dis[j][i]," \n"[j==n]);
}
// for(int i=0;i<8;i++) for(int j=0;j<8;j++)
// printf("%d%c",disc[i][j]," \n"[j==7]);
for(int i=1;i<=n;i++){
for(int j=max(1,i-15);j<=i;j++){
int mn=i-j;
for(int k=0;k<8;k++) chkmin(mn,dis[j][k]+dis[i][k]+1);
merge(mn,1);
} if(i-16>=1){
int msk=0;
for(int j=0;j<8;j++) msk|=(dis[i-16][j]-disc[s[i-16]-'a'][j])<<j;
cnt[msk][s[i-16]-'a']++;
} for(int j=0;j<MAXP;j++) for(int k=0;k<8;k++) if(cnt[j][k]){
int mn=INF;
for(int l=0;l<8;l++) chkmin(mn,dis[i][l]+disc[k][l]+(j>>l&1)+1);
merge(mn,cnt[j][k]);
}
} printf("%d %lld\n",res,resc);
return 0;
}

Codeforces 718E - Matvey's Birthday(思维题)的更多相关文章

  1. C. Nice Garland Codeforces Round #535 (Div. 3) 思维题

    C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  2. Codeforces 515C 题解(贪心+数论)(思维题)

    题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...

  3. Codeforces 1188B - Count Pairs(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 虽说是一个 D1B,但还是想了我足足 20min,所以还是写篇题解罢( 首先注意到这个式子里涉及两个参数,如果我们选择固定一个并动态维护另 ...

  4. Codeforces 1365G - Secure Password(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 首先考虑一个询问 \(20\) 次的方案,考虑每一位,一遍询问求出下标的这一位上为 \(0\) 的位置上值的 bitwise or,再一遍 ...

  5. Codeforces 1129E - Legendary Tree(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 考虑以 \(1\) 为根,记 \(siz_i\) 为 \(i\) 子树的大小,那么可以通过询问 \(S=\{2,3,\cdots,n\}, ...

  6. CodeForces - 427A (警察和罪犯 思维题)

    Police Recruits Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  7. codeforces 848B Rooter's Song 思维题

    http://codeforces.com/problemset/problem/848/B 给定一个二维坐标系,点从横轴或纵轴垂直于发射的坐标轴射入(0,0)-(w,h)的矩形空间.给出点发射的坐标 ...

  8. Codeforces 729D Sea Battle(简单思维题)

    http://codeforces.com/contest/738/problem/D https://www.cnblogs.com/flipped/p/6086615.html   原 题意:海战 ...

  9. @codeforces - 718E@ Matvey's Birthday

    目录 @description@ @solution@ @accepted code@ @detail@ @description@ 给定一个长度为 n 的字符串 s,保证只包含前 8 个小写字母 ' ...

随机推荐

  1. 解决pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.

    参考链接[侵权删] https://www.jianshu.com/p/3378fa827924 https://yq.aliyun.com/articles/619208 问题描述:在Windows ...

  2. 【UE4 C++】 UnrealPak 与 Pak 的制作、挂载、加载

    简介 通过 UnrealPak,可以将资源打包成 Pak 文件 Pak文件是UE4游戏生成的数据包文件. Pak 之前一般先有 Cooked 步骤,将资源烘焙为对应平台支持的资源 一般打包后的项目使用 ...

  3. [软工顶级理解组] 团队规划和任务拆解(Beta)

    目录 需求再分析 功能增减 管理改进 任务分解 人员管理 需求再分析 在Alpha阶段,我们的产品得到了用户的广泛好评,但是还是存在一些问题. 登录不稳定,登录速度慢等问题:这是北航VPN本身的不稳定 ...

  4. STM32必学的时钟系统

    STM32的时钟系统 相较于51单片机,stm32的时钟系统可以说是非常复杂了,我们现在看下面的一张图:   上图说明了时钟的走向,是从左至右的从时钟源一步步的分配给外设时钟.需要注意的是,上图左侧一 ...

  5. python画图的工具及网站

    ①Gallery - Matplotlib 3.4.3 documentation 学会模仿并超越 ②Examples - Apache ECharts js网页端动态展示 ③WEB色見本 原色大辞典 ...

  6. 因为一个小小的Integer问题导致阿里一面没过,遗憾!

    面试题:new Integer(112)和Integer.valueOf(112)的区别 面试官考察点猜想 这道题,考察的是对Integer这个对象原理的理解,关于这道题的变体有很多,我们会一一进行分 ...

  7. insertion-sort-list leetcode C++

    Sort a linked list using insertion sort. C++ /** * Definition for singly-linked list. * struct ListN ...

  8. Docker 搭建 Jenkins 持续集成自动化构建环境

    1.Docker镜像拉取 Jenkins 环境命令 docker pull jenkins/jenkins:lts 查看下拉取的镜像 docker images 2.通过容器编排方式构建 Jenkin ...

  9. 1. 处理静态资源 2. controller如何接受请求得参数 3. 如何把controller得数据保存到view. 4. 在controller如何完成重定向到指定路径 5. controller返回json数据

    1. 1. 处理静态资源2. controller如何接受请求得参数3. 如何把controller得数据保存到view.4. 在controller如何完成重定向到指定路径5. controller ...

  10. vscode 导入第三方jar包(添加外部JAR)

    添加 jar包 至根目录下lib文件夹,在 .classpath 文件内添加 jar 路径. 注意:新添加的 jar路径 在"src"和"bin"之间,否则无法 ...