解析

比较复杂的一道题
看数据范围,我们肯定要从种类很少的颜色入手

因为第二种加边方式和颜色密切相关
所以设计disi,kdis_{i,k}disi,k​表示 i 号节点到颜色为 k 的节点的最小步数
通过对每个k bfs一遍就能得出答案
然后两个点之间的距离就可以写出转移式:
fi,j=min⁡(∣i−j∣,min⁡k8disi,k+disj,k+1)f_{i,j}=\min (|i-j|, \min_k^8dis_{i,k}+dis_{j,k}+1)fi,j​=min(∣i−j∣,kmin8​disi,k​+disj,k​+1)
考虑这样我们就得到了一种n2n^2n2的算法

考虑如何加速
首先,由于最差情况就是aabbcc…这样的情形,答案不会超过15,所以第一项我们只需要在距离[i-15,i-1]的区间考虑,可以暴力求解

关键是对后面一项的处理

设计coli,jcol_{i,j}coli,j​表示从任意 i 颜色的块走到任意 j 颜色的块的最小步数
这个也可以在bfs时顺便转移
可以得到一个不等关系式:
colai,j≤disi,j≤colai,j+1col_{a_i,j}\leq dis_{i,j}\leq col_{a_i,j}+1colai​,j​≤disi,j​≤colai​,j​+1
为什么?
也比较显然,如果任何一个不等关系不符合,col和dis数组就会在bfs时互相更新,使这个不等关系重新满足

所以,我们的dis-col的差值只可能为0或1,我们可以把8个对应的差值状态压缩,然后一起求解

实现上,建议把所有状态的结果预处理出来,会在瓶颈部分少一个8的循环,应该快很多

代码

#include<bits/stdc++.h>const int N=1e5+100;
const int mod=1e9+7;
#define ll long long
using namespace std;
inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;int col[9][9],dis[N][9],a[N];
bool vis[N];
char s[N];
int q[N],st,ed;
int dx[3]={0,1,-1};
vector<int>v[9];
void bfs(int k){memset(vis,0,sizeof(vis));st=1;ed=0;for(int i=1;i<=n;i++){if(a[i]==k) q[++ed]=i,vis[i]=1;}col[k][k]=0;while(st<=ed){int now=q[st++];for(int i=1;i<=2;i++){int to=now+dx[i];if(vis[to]||to==0||to>n) continue;vis[to]=1;dis[to][k]=dis[now][k]+1;q[++ed]=to;}if(col[k][a[now]]==1e9){col[k][a[now]]=dis[now][k];for(int i=0,tp=v[a[now]].size();i<tp;i++){int x=v[a[now]][i];if(!vis[x]){dis[x][k]=dis[now][k]+1;q[++ed]=x;vis[x]=1;}}}}return;
}
int mi[15],cst[2060][2060];
int sta[N],num[2060];
int main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();scanf(" %s",s+1);for(int i=1;i<=8;i++){for(int j=1;j<=8;j++) col[i][j]=1e9;}for(int i=1;i<=n;i++) a[i]=s[i]-'a'+1,v[a[i]].push_back(i);for(int i=1;i<=8;i++) bfs(i);mi[0]=1;for(int i=1;i<=11;i++) mi[i]=mi[i-1]<<1;for(int i=0;i<mi[11];i++){for(int j=0;j<mi[11];j++){int a=(i>>8)+1,b=(j>>8)+1;int res=2e9;for(int k=1;k<=8;k++){res=min(res,col[a][k]+1+col[b][k]+((i&mi[k-1])?1:0)+((j&mi[k-1])?1:0));}cst[i][j]=res;}}for(int i=1;i<=n;i++){int s=a[i]-1,o=a[i];for(int k=8;k>=1;k--){s<<=1;if(dis[i][k]>col[o][k]) s|=1;}sta[i]=s;}int ans(0);ll sum(0);for(int i=1;i<=n;i++){for(int j=max(i-15,1);j<i;j++){int w=min(i-j,cst[sta[i]][sta[j]]);if(w>ans){ans=w;sum=1;}else if(w==ans) sum++;}for(int s=0;s<mi[11];s++){if(!num[s]) continue;if(cst[s][sta[i]]>ans) ans=cst[s][sta[i]],sum=num[s];else if(cst[s][sta[i]]==ans) sum+=num[s];}if(i>=16) num[sta[i-15]]++;}//printf("st[1]=%d st[7]=%d\n",sta[1],sta[7]);//printf("dis[1][1]=%d col[3][1]=%d\n",dis[1][1],col[3][1]);printf("%d %lld\n",ans,sum);return 0;
}

CF718E Matvey‘s Birthday(状压、bfs、暴力、分类讨论)相关推荐

  1. codevs 2594 解药还是毒药(状压+bfs)

    题目描述 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别的病症(你可能会问那-那是解 ...

  2. 【日常学习】【状压BFS】codevs2594 解药还是毒药题解

    题目描述 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别的病症(你可能会问那-那是解 ...

  3. [HNOI2006]最短母串问题——AC自动机+状压+bfs环形处理

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 32MB Input 第一行是一个正整数n(n< ...

  4. 小红的rpg游戏 (状压 bfs

    添加链接描述 因为怪物数量小于等于10 所以可以枚举每个怪物是否选择通过 使用状压枚举的方式从当前位开始bfs 选择dist最小的可能性 #include<bits/stdc++.h> u ...

  5. hdu4771 Stealing Harry Potter's Precious (状压+bfs)

    Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and hi ...

  6. jzoj4016-圈地为王【状压,bfs,几何】

    正题 题目链接:https://jzoj.net/senior/#contest/show/3011/1 题目大意 n∗mn*mn∗m的格子,格子之间有道路,对于每个iii就走过最短的回路使得 圈住i ...

  7. bzoj 3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(状压+BFS)

    3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 94  Solve ...

  8. 【训练题66:状压暴力 | 子集dp】Greater Integer, Better LCM | 2021牛客暑期多校训练营5

    题意 Greater Integer, Better LCM | 2021牛客暑期多校训练营5 给你 a,b,ca,b,ca,b,c ,你需要找到一对 x,yx,yx,y ,满足: lcm(a+x,b ...

  9. 状压DP学习总结 (详解,适合没状压dp基础的人学习,还在更新中,,,,)

    本次博客,主要是给学弟学妹们讲解一下状压dp,不适合有基础的同学观看,可能会浪费时间,因为偏基础 先来最简单的一个吧   http://acm.hdu.edu.cn/showproblem.php?p ...

  10. [CQOI2012] 局部极小值(状压DP + 容斥 + 搜索)

    problem luogu-P3160 solution 这么小的数据范围,非暴力不状压.暴力 O(28!)O(28!)O(28!) 呵呵呵可以拉走了. 我们不妨从小到大填数字,这样如果局部极小值点还 ...

最新文章

  1. JetBrains——账户登录错误(JetBrains Account Error:JetBrains Account connection error: www.jetbrains.com)解决方案
  2. not in SQL语句转化为 not exists
  3. n1运行linux,斐讯 N1 运行 ArchLinuxARM
  4. 荣耀正式加入GSMA 成为其企业成员单位
  5. 照片快照清除 android,如何在Android中删除和恢复照片
  6. c语言可以调用汇编语言吗,C语言与汇编语言混编方式
  7. python print输出字符串报错
  8. python 获取二维数组所有元素
  9. [学习笔记] [数据分析] 01.Python入门
  10. 分布式锁的原理和实现详解
  11. 基于java的田径运动会报名系统
  12. 使用Laravel和Vue.js2.5进行服务器端渲染
  13. 解决因多网卡导致dubbo注册到ZK的IP错误问题,dubbox(当当,2.8.4)升级至dubbo(Apache,2.7.15)并集成
  14. 一条机器“龙”,堪称史上最快异形机器人!
  15. linux下挂载移动硬盘(ntfs格式),Linux下挂载移动硬盘(NTFS格式)
  16. Win7下IIS安装PHP环境
  17. HDU 1859 最小长方形
  18. 如何给table里的input赋值
  19. 那些年,在Fragment中犯的错
  20. cadworx管道设计基础到精通教程

热门文章

  1. 什么样的程序员会让人讨厌
  2. 2014全国计算机二级ms office,2014计算机二级MS Office真题及答案
  3. float型y取值在1.0c语言表达式,2011年全国计算机二级C语言模拟试题及答案(14)...
  4. 早教机器人刷固件_机器人线刷包_机器人刷机包_机器人固件包_机器人救砖包 - 线刷宝ROM中心...
  5. android studio插入数据表中没有_学Java能拿高薪吗 Java中常见排序算法有哪些
  6. mysql中如何计算党龄_党员的党龄如何计算?
  7. 信息技术上册教案了解计算机,信息技术上册全册教案
  8. 中断原理在计算机中的应用,最新 计算机原理与应用 复习3-判断题
  9. 西北工业大学计算机毕业论文,光纤通信发射机本科毕业论文 西北工业大学.docx...
  10. linux中wine yum安装,分享|在基于RedHat或Debian的系统上安装 Wine 1.7