【CF】Day69——⭐Codeforces Round 897 (Div. 2) D (图论 | 思维 | DFS | 环)

D. Cyclic Operations

题目:

思路:

非常好的一题

对于这题我们要学会转换和提取条件,从特殊到一般

我们可以考虑特殊情况先,即 k = n 和 k = 1时,对于 k = 1,我们可以显然发现必须满足 b[i] = i,而对于 k = n 时,我们可以发现一个特点,比如对于 2 3 1 这个例子,我们可以一个一个构造,对于 2,我们肯定是构造一个 1 2 这样的结构,对于 3 那就是 2 3,对于 1,那就是 3 1,所以最后的 l 可以是 1 2 3

我们试着进一步讨论,可以发现其实这样的一个结构:第 i 个节点指向第 b[i] 个节点

比如 2 3 1,即 1 要指向 2,2要指向 3,3要指向 1,最后形成一个图:1 -> 2 -> 3 -> 1,我们发现这其实就是一个环,并且长度为 n,我们试着扩展一下

对于 2 3 5 3 4,我们假设 k = 3,那么对于前三个我们可以这样构造 l = 1 2 3,构造完后就是 2 3 1 0 0,对于后三个我们这样构造 l = 3 5 4,这样最后就是 2 3 5 3 4了,我们来看看这个答案是否也存在环,构建图:1->2->3->5->4->3 我们发现存在 3 5 4 这个环,并且我们还可以发现其长度恰好也为 k

所以我们可以猜测一个结论:最后构造出来的图如果有环则环的长度一定为 k

显然这时可行的,为什么呢?由于我们每次选取 k 个数构造的时候都是先构造一个环,而下次的构造如果和之前的环有交集那么就一定会断边来构造一个新环,所以最后一个连通分量里面只有一个环,且这个环的长度一定得是 k,所以我们就可以按照结论模拟即可

代码:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"

void solve()
{
    int n, k;
    cin >> n >> k;
    vector<int> b(n+1),vis(n+1,0);
    for (int i = 1; i <= n; i++)
    {
        cin >> b[i];
    }
    if (k == 1)
    {
        for (int i = 1; i <= n; i++)
        {
            if (b[i] != i)
            {
                no;
                return;
            }
        }
        yes;
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        if (vis[i])
            continue;
        int fa = i;
        while (!vis[fa])
        {
            vis[fa] = i;
            fa = b[fa];
        }
        if (vis[fa] == i)
        {
            int son = fa;
            int len = 0;
            do
            {
                len++;
                son = b[son];
            } while (son != fa);
            if (len != k)
            {
                no;
                return;
            }
        }
    }
    yes;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
相关推荐
liulilittle29 分钟前
IP校验和算法:从网络协议到SIMD深度优化
网络·c++·网络协议·tcp/ip·算法·ip·通信
bkspiderx2 小时前
C++经典的数据结构与算法之经典算法思想:贪心算法(Greedy)
数据结构·c++·算法·贪心算法
中华小当家呐3 小时前
算法之常见八大排序
数据结构·算法·排序算法
沐怡旸4 小时前
【算法--链表】114.二叉树展开为链表--通俗讲解
算法·面试
一只懒洋洋4 小时前
K-meas 聚类、KNN算法、决策树、随机森林
算法·决策树·聚类
方案开发PCBA抄板芯片解密5 小时前
什么是算法:高效解决问题的逻辑框架
算法
songx_996 小时前
leetcode9(跳跃游戏)
数据结构·算法·游戏
小白狮ww6 小时前
RStudio 教程:以抑郁量表测评数据分析为例
人工智能·算法·机器学习
AAA修煤气灶刘哥6 小时前
接口又被冲崩了?Sentinel 这 4 种限流算法,帮你守住后端『流量安全阀』
后端·算法·spring cloud
kk”7 小时前
C语言快速排序
数据结构·算法·排序算法