Jellyfish and Math

这种花里胡哨的题目一看就是转化成图论最短路,然而我却不知道怎么转。。。

看这篇题解,写的很清楚

题解最后的处理,相当于在当前询问中,\(a,b,m\)会对应八个状态中的一些状态,同时\(c,d\)对这些状态的终点也有要求;而八个状态中除了这些状态,想变什么就变什么

update 2024.5.21

我自己想出来啦!!!!

先运用位运算的经典技巧逐位考虑,这样的话就可以发现最多\(8\)种状态了

update 2024.8.16

写了代码,学到很多

首先为了不超时肯定要预处理,但是如果我们考虑八个状态的全排列,那么肯定会超时(比如说\(a=(10)_2,b=(01)_2,m=(11)_2\)\(a=(01)_2,b=(10)_2,m=(11)_2\)本质上是一样的,只不过前者状态\((101)_2\)\((011)_2\)前面,后者\((101)_2\)\((011)_2\)后面,但是操作过程肯定是等价的),因为状态数太多了,于是考虑简化,不难想到将所有状态从小到大排序组成一个状态,这样子不同的起点总数就是\(\overset{8}{\underset{i=1}{\sum}}C_8^i\),当选出\(i\)个状态的时候,我们BFS的过程中\(m\)是不用变的,所以最多遍历的状态数为\(2^{2i}\),于是复杂度为\(\overset{8}{\underset{i=1}{\sum}}C_8^i2^{2i}\),写个代码跑一下发现为四十万,根本不用担心,用一个map存下就好了

问题是map的结构,map是要定义小于号的(因为本质是平衡树,要进行比较来维护),所以map的template别写些奇奇怪怪的东西。我们将一个状态表示为(a<<(cnt<<1))|(b<<cnt)|m(其中cnt就是上文的\(i\),即选出多少个状态),我们现在想要得到的就是dis[cnt][s][t],表示当选出cnt个状态的时候,从状态st的最短路,于是我们开map<int,int> dis[cnt][t],注意这个map开出来,dis[cnt][t][s]就表示当选出cnt个状态的时候,从状态st的最短路,也就是说“键”是起点而不是终点;然后跑BFS就好了

posted @ 2024-03-28 22:47  最爱丁珰  阅读(5)  评论(0编辑  收藏  举报