首页 > 其他分享 >Solution - Codeforces 1681E Labyrinth Adventures

Solution - Codeforces 1681E Labyrinth Adventures

时间:2024-11-14 21:45:50浏览次数:1  
标签:std Labyrinth Solution int dx dy 1681E operatorname dis

能够发现这个最短路的形态一定是从低层一层一层走到高层的。

那么这就说明若起点终点对应层数为 \(x, y\)。
若 \(x = y\) 则直接算,就是曼哈顿距离。
否则不妨钦定 \(x < y\)(不满足就交换,不影响结果),那么层数 \(z\in [x, y)\) 的其中一个门肯定都会被经过。

于是考虑把 \(\operatorname{dis}((x_1, y_1), (x_2, y_2))\) 拆成到同一层两个门的距离的和的最小值。
记在路径之中经过的其中一层的两个门为 \((x_3, y_3), (x_4, y_4)\),那么就可以拆成 \(\min\{\operatorname{dis}((x_1, y_1), (x_3, y_3)) + \operatorname{dis}((x_3, y_3), (x_2, y_2)), \operatorname{dis}((x_1, y_1), (x_4, y_4)) + \operatorname{dis}((x_4, y_4), (x_2, y_2))\}\)。

同时对于 \(\operatorname{dis}((x_1, y_1), (x_3, y_3))\) 也可以继续拆下去。
记 \((x_1, y_1)\) 所在层的两个门为 \((x_5, y_5), (x_6, y_6)\),那么可以类似的拆为 \(\min\{\operatorname{dis}((x_1, y_1), (x_5, y_5)) + \operatorname{dis}((x_5, y_5), (x_3, y_3)), \operatorname{dis}((x_1, y_1), (x_6, y_6)) + \operatorname{dis}((x_6, y_6), (x_3, y_3))\}\)。

对于 \(\operatorname{dis}((x_1, y_1), (x_5, y_5))\) 因为同层关系就是好算的了。

于是能够发现只需要知道门的最短路距离就可以得到答案了。

但是考虑到门的个数还是 \(\mathcal{O}(n)\) 的,直接跑还是不太行。
但是注意到每次询问对应的是一个区间,于是可以考虑分治。

具体的,考虑处理到 \([l, r]\),那么记 \(m = \lfloor\frac{l + r}{2}\rfloor\)。
考虑就以 \(m\) 层的门为起点,跑出与其他 \([l, r]\) 层内的门的最短路。
那么对于一个层数在 \([x, y](l\le x\le y\le r)\) 的询问,若这个层数跨过了 \(m\) 层的门,即 \(x\le m < y\),那么就可以在此统计贡献了。

对于还没有统计到的询问,考虑分成两部分 \([l, m], (m, r]\),继续递归下去处理。

时间复杂度 \(\mathcal{O}((n + q)\log n)\)。

#include<bits/stdc++.h>
using ll = long long;
constexpr ll inf = 1e18;
constexpr inline int dis(int x1, int y1, int x2, int y2) {
   return abs(x1 - x2) + abs(y1 - y2);
}
constexpr inline int dep(int x, int y) {
   return std::max(x, y);
}
using Z = std::tuple<int, int, int, int, int>;
constexpr int maxn = 1e5 + 10, maxm = 2e5 + 10;
int dx[maxn][2], dy[maxn][2];
ll ans[maxm];
ll f[2][maxn][2];
inline void solve(int l, int r, std::vector<Z> qry) {
   if (l >= r) return ;
   int mid = l + r >> 1;
   for (int op : {0, 1}) {
      auto d = f[op];
      d[mid][op] = 0, d[mid][op ^ 1] = dis(dx[mid][0], dy[mid][0], dx[mid][1], dy[mid][1]);
      for (int i = mid - 1; i >= l; i--) {
         d[i][0] = 1ll + std::min(d[i + 1][0] + dis(dx[i][0] + 1, dy[i][0], dx[i + 1][0], dy[i + 1][0]), 
                                  d[i + 1][1] + dis(dx[i][0] + 1, dy[i][0], dx[i + 1][1], dy[i + 1][1]));
         d[i][1] = 1ll + std::min(d[i + 1][0] + dis(dx[i][1], dy[i][1] + 1, dx[i + 1][0], dy[i + 1][0]),
                                  d[i + 1][1] + dis(dx[i][1], dy[i][1] + 1, dx[i + 1][1], dy[i + 1][1]));
      }
      for (int i = mid + 1; i < r; i++) {
         d[i][0] = 1ll + std::min(d[i - 1][0] + dis(dx[i - 1][0] + 1, dy[i - 1][0], dx[i][0], dy[i][0]),
                                  d[i - 1][1] + dis(dx[i - 1][1], dy[i - 1][1] + 1, dx[i][0], dy[i][0]));
         d[i][1] = 1ll + std::min(d[i - 1][0] + dis(dx[i - 1][0] + 1, dy[i - 1][0], dx[i][1], dy[i][1]),
                                  d[i - 1][1] + dis(dx[i - 1][1], dy[i - 1][1] + 1, dx[i][1], dy[i][1]));
      }
   }
   std::vector<Z> qryL, qryR;
   for (auto [x1, y1, x2, y2, id] : qry) {
      int dep1 = dep(x1, y1), dep2 = dep(x2, y2);
      if (dep1 <= mid && mid < dep2) {
         ans[id] = inf;
         for (int op : {0, 1}) {
            auto d = f[op];
            ll d1 = std::min(d[dep1][0] + dis(x1, y1, dx[dep1][0], dy[dep1][0]), 
                             d[dep1][1] + dis(x1, y1, dx[dep1][1], dy[dep1][1]));
            ll d2 = std::min(d[dep2 - 1][0] + dis(x2, y2, dx[dep2 - 1][0] + 1, dy[dep2 - 1][0]),
                             d[dep2 - 1][1] + dis(x2, y2, dx[dep2 - 1][1], dy[dep2 - 1][1] + 1));
            ans[id] = std::min(ans[id], 1ll + d1 + d2);
         }
      } else if (dep2 <= mid) {
         qryL.emplace_back(x1, y1, x2, y2, id);
      } else {
         qryR.emplace_back(x1, y1, x2, y2, id);
      }
   }
   solve(l, mid, qryL), solve(mid + 1, r, qryR);
}
int main() {
   int n, m;
   scanf("%d", &n);
   for (int i = 1; i < n; i++) {
      for (int j : {0, 1}) {
         scanf("%d%d", &dx[i][j], &dy[i][j]);
      }
   }
   scanf("%d", &m);
   std::vector<Z> qry;
   for (int i = 1; i <= m; i++) {
      int qx[2], qy[2];
      scanf("%d%d%d%d", &qx[0], &qy[0], &qx[1], &qy[1]);
      if (dep(qx[0], qy[0]) == dep(qx[1], qy[1])) {
         ans[i] = dis(qx[0], qy[0], qx[1], qy[1]);
         continue;
      }
      if (dep(qx[0], qy[0]) > dep(qx[1], qy[1])) {
         std::swap(qx[0], qx[1]), std::swap(qy[0], qy[1]);
      }
      qry.emplace_back(qx[0], qy[0], qx[1], qy[1], i);
   }
   solve(1, n, qry);
   for (int i = 1; i <= m; i++) {
      printf("%lld\n", ans[i]);
   }
   return 0;
}

标签:std,Labyrinth,Solution,int,dx,dy,1681E,operatorname,dis
From: https://www.cnblogs.com/rizynvu/p/18546867

相关文章

  • Solution - Codeforces 1190C Tokitsukaze and Duel
    考虑到两人对应的操作是相同的,于是可以从对称的角度来思考。考虑到在先手做出操作后,后手一个较为特殊的操作是不做任何影响,也就是重复先手的操作。能够发现如果对于后手这不能必胜,那么他一定不会去产生影响,并又把这个局面留给先手,相当于是先后手的交换。对于先手又是同样的,因为......
  • Solution - Codeforces 1394B Boboniu Walks on Graph
    考虑先分析最后的图会长成什么样。因为每个点都只会连出一条有向边,且最后还能走回自己。所以可以知道的是图会有许多个环来组成,且每个环都无交。但是这个判定条件明显不是很优秀,考虑继续转化。考虑到对于一个有向环,每个点的出度和入度都需要为\(1\)。那么出度为\(1\)题目......
  • Solution - Codeforces 1217E Sum Queries?
    对于这个“好的”的判定条件看起来有点奇怪,不妨结合上题目要求的“最小\(sum\)”一起考虑。因为要最小化\(s_p\),所以一个比较直观的想法是先从选的数个数入手。考虑到如果选的只有\(1\)个数\(a_i\),那么\(sum=a_i\),一定是好的,排除。如果选的是\(2\)个数\(a_i,a_j\),......
  • LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images
    传统的大多模态模型(LargeMultimodalModel,LMM)关注于固定的尺寸和有限的分辨率。本文以GPT-4V和LLaVa-1.5为代表,揭示了视觉编码策略的根本性系统缺陷。本文指出大多模态模型可以有效地感知任何长宽比和高分辨率的图像。概述为了实现LMM模型在多种长宽比和高分辨率的图像感......
  • Solution - P9090 「SvR-2」G64
    小爆个标,给出一个\(\mathcal{O}(n+q+\sqrt{x}+\log\operatorname{mod})\)的做法。可能写的有点意识流了,可以结合代码理解或者私信我吧qaq。首先对于最大独立集有DP:设\(f'_{i,0/1}\)表示考虑\(i\)的子树,\(i\)选没选的最大独立集点数。转移就是\(f'_{i,0}......
  • [论文阅读] High-Resolution Image Synthesis with Latent Diffusion Models
    写在前面原文:https://arxiv.org/abs/2112.10752Github:https://github.com/CompVis/latent-diffusion?tab=readme-ov-file参考:https://stable-diffusion-art.com/how-stable-diffusion-work/关键词:stablediffusion,LDMs阅读理由:对DM高消耗的优化,解决速度问题。看一下优化思路,......
  • Solution - Atcoder Atcoder ARC137C Distinct Numbers
    如果尝试去刻画这个问题,会发现非常复杂,于是不妨一步一步来。考虑Alice的第一步,此时Alice操作的位置是固定的。考虑把\(a_n\)移到一个位置后,接下来的\(\max\)是\(a_{n-1}\)或\(a_n\),Bob对应也只能这么操作。注意到Bob也有可能操作的是\(a_n\),这看起来就很特殊......
  • Exploring Qualcomm IPQ5332 and IPQ5322: The Champions of WiFi 7 Solutions
    AsWiFi7technologyrapidlyadvances,Qualcomm'sIPQ5332andIPQ5322chipshaveemergedaspopularchoicesforusers.Thesetwochipsnotonlyexhibitoutstandingperformancebutalsopossessuniquefeaturestailoredtodifferentnetworkrequirement......
  • 【题解】Solution Set - NOIP2024集训Day58 字符串
    【题解】SolutionSet-NOIP2024集训Day58字符串https://www.becoder.com.cn/contest/5658「CF1466G」SongoftheSirens考虑对于\(s_i\),算钦定必须覆盖到\(t_i\)的匹配个数\(f_i\)。注意到\(s\)每次长度都会\(\times~2\)左右,其长度在\(O(\log|w|)\)的时候就......
  • [POI2012] Cloakroom - Solution
    POI2012Cloakroom题目描述(搬自洛谷)有\(n\)件物品,每件物品有三个属性\(a_i,b_i,c_i\(a_i<b_i)\)。再给出\(q\)个询问,每个询问由非负整数\(m,k,s\)组成,问是否能够选出某些物品使得:对于每个选的物品\(i\),满足\(a_i\lem\)且\(b_i>m+s\)。所有选出物品的\(c_i......