ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P2582 函数

2022-08-26 21:03:17  阅读:287  来源: 互联网

标签:洛谷 函数 int mid gx P2582 Maxn size


函数 - 洛谷

可以发现性质 \(g(f^m(x))=f^m(g(x))\) 。

若设左侧 \(x\) 所在环大小为 \(size(x)\) ,右侧 \(g(x)\) 所在环的大小为 \(size(gx)\) 。

可以得到,\(size(gx)\mid size(x)\) 。

这是因为左侧下标呈循环,右侧的值呈循环,若环的大小不满足 \(size(gx)\mid size(x)\) ,必然会出现矛盾。

于是我们首先 \(O(n)\) 求出每个环的大小,枚举约数计算最小满足条件的 \(g(x)\) 即可,然后后面的数就可以迭代填出。

#include <bits/stdc++.h>
const int Maxn = 8e5 + 5;
int n, f[Maxn], g[Maxn], sz[Maxn], num[Maxn];
bool vis[Maxn];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &f[i]);
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]) continue;
        int x = i, cnt = 0;
        do {x = f[x], ++cnt;} while(x != i);
        do {x = f[x]; sz[x] = cnt; vis[x] = true;} while(x != i);
        if (!num[cnt]) num[cnt] = x;
    }
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]) continue;
        int sav = 0x3f3f3f3f;
        for (int j = 1; j * j <= sz[i]; j++)
        {
            if (sz[i] % j == 0)
            {
                if (num[j]) sav = std::min(sav, num[j]);
                if (j * j != sz[i] && num[sz[i] / j])
                    sav = std::min(sav, num[sz[i] / j]);
            }
        }
        int x = i;
        do {g[x] = sav, vis[x] = true, x = f[x], sav = f[sav]; } while(x != i);
    }
    for (int i = 1; i <= n; i++)
        printf("%d ", g[i]);
    return 0;
}

标签:洛谷,函数,int,mid,gx,P2582,Maxn,size
来源: https://www.cnblogs.com/mklzc/p/16629240.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有