首页 > 其他分享 >ABC372 F 题解

ABC372 F 题解

时间:2024-09-22 20:36:08浏览次数:16  
标签:map log 咕咕 题解 复杂度 转移 ABC372

F - Teleporting Takahashi 2

先把问题转化一下:把环断开成链,复制 \((K + 1)\) 层,每走一步就相当于前进一层:

可以想到一个简单的 dp:设 \(f(i, j)\) 表示走到第 \(i\) 层第 \(j\) 个位置的方案数。

  • 初始化:\(f(0, 1) = 1\),其它均为 \(0\),表示 Takahashi 从第 \(0\) 层的 \(1\) 位置出发。
  • 答案统计:\(ans = \sum_{i = 1}^{N} f(K + 1, i)\)。
  • 转移:\(f(i, j) = \sum_{v \in pre(j)} f(i - 1, v)\),其中 \(pre(j)\) 能通过一条边直接到达 \(j\) 的点的集合。

上述做法的时空复杂度都是 \(O(NK)\)。由于每层的状态只和前一层有关,我们可以简单地用滚动数组把空间复杂度优化到 \(O(N)\),但时间复杂度似乎不太好优化。(提交记录

(下面为了方便,把点的编号转为从 \(0\) 开始。实际上,对于环上的问题,0-indexed 往往都更方便。)

突破口在于 \(M\)。我们先假设 \(M = 0\)。这时,所有的边都形如 \((i, i + 1)\)(在环的意义下),并且所有的点 \(j\) 都只能从前一层的 \(j-1\) 这一个位置转移过来,也就是 \(f(i, j) = f(i-1, j-1)\)。换句话说,我们把 \(f(i - 1, *)\) ”右移“一位就得到了 \(f(i, *)\):

这启示我们转移时,不用暴力地赋值 \(f(i, *)\),而是用一个变量 \(be\) 代表当前数组把哪个下标当作“\(1\)”,每次转移到下一层,就让 \(be \gets (be - 1) \bmod N\) (也就是在环上自减 \(1\))。用 \(f'\) 表示代码中的数组:一开始在第 \(0\) 层,\(be = 1\),于是 \(f'(1) = f(0, 1), f'(2) = f(0, 2), \dots, f'(N) = f(0, N)\)。转移到第 \(1\) 层以后,\(be = N\),于是 \(f'(N) = f(1, 1), f'(1) = f(1, 2), \dots, f'(N-1) = f(N)\)。这样,转移时我们只需更新 \(be\),而不用把 \(f'\) 全部扫一遍。

当 \(M \not= 0\) 时呢?我们注意到,只有 \(M\) 条边不是 \((i, i+1)\) 类型的,而 \(M \le 50\),因此可以暴力地枚举这些边来转移。

具体实现时,下标转化的细节有点多。此外,为了防止新旧版本的 \(f'\) 混淆,我用了 map 来存储那些被 \(M\) 条边连接的点的值。这使得时间复杂度乘上一个 \(\log\),或许更精细的做法可以去掉这个 \(\log\),但我感觉用 map 方便一些。

时间复杂度 \(O(N + KM \log M)\),空间复杂度 \(O(N + M)\)。

参考代码:

vector<int> f(N);
f[0] = 1;
int be = 0;
map<int, int> tmp;
for(int i = 1; i <= K; i++)
{
    tmp.clear();
    be = (be + N - 1) % N;
    for(auto ed: e)
    {
        int u = ed.u, v = ed.v;
        u = (be + 1 + u) % N, v = (be + v) % N;
        if(tmp.find(v) == tmp.end()) tmp[v] = f[v];
        tmp[v] = (f[u] + tmp[v]) % MOD;
    }
    for(auto p: tmp)
        f[p.first] = p.second;
}

int ans = 0;
for(int x: f)
    ans = (ans + x) % MOD;
cout << ans << endl;

提交记录

(注:图源:ATcoder 的官方题解

G - Ax + By < C

咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕咕

while(1) printf("gugugu");

I can't solve this problem by myself.

标签:map,log,咕咕,题解,复杂度,转移,ABC372
From: https://www.cnblogs.com/dengstar/p/18425814

相关文章

  • ABC372 Review
    ABC372ReviewA语言基础题B类似于二进制拆分,就像跳LCA的时候一样,尽可能多地选大的即可。C一个位置的字母被改变仅仅会对相邻两个位置之类的答案产生影响,暴力统计即可。D对于每一个\(i\)去暴力地统计\(j\)显然是不可行的,所以可以转而想一想每个\(j\)会对答案产生多......
  • 【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解
    【洛谷】P10417[蓝桥杯2023国A]第K小的和的题解题目传送门题解CSP-S1补全程序,致敬全A的答案,和神奇的预言家。写一下这篇的题解说不定能加CSP2024的RP代码#include<bits/stdc++.h>#definelowbit(x)x&(-x)#defineendl"\n"usingnamespacestd......
  • 【题解】【枚举】—— [NOIP2014 普及组] 比例简化
    【题解】【枚举】——[NOIP2014普及组]比例简化[NOIP2014普及组]比例简化题目背景题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.思路解析2.AC代码[NOIP2014普及组]比例简化通往洛谷的传送门题目背景NOIP2014普及组T2题目描述在社交媒体......
  • 第31次CCF-CSP认证考试 第一题 坐标变换(其一)满分题解
    第31次CCF-CSP认证考试第一题坐标变换(其一)写在前面的话这道题偏简单,我们废话不多说,直接上代码。老系统的链接:旧系统(不过只有第三十二次以及之前的,第三十三及以后的只能在新系统里提交查看分数)。代码#include<iostream>usingnamespacestd;intmain(){ intn,m; ......
  • 正方形计数 题解
    题意简述给出一个\(n\timesn\)的格点平面,有\(q\)次询问,求有多少正方形以\((x,y)\)为某一顶点,满足这个正方形顶点均在格点上,且边长为有理数。\(l\leq10^5\),\(q\leq5\times10^5\)。题目分析看到边长为有理数,想到「毕达哥拉斯三元组」("Pythagoreantriple",简称「......