• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yumiym765

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

F. Minimize Fixed Points

F. Minimize Fixed Points

\(\hspace{20px}\)有长度为 \(n\) 的排列 \(p\),如果对所有 \(2 \leq i \leq n\),有 \(\gcd(p_i, i) > 1\),则称其为好排列。在长度为 \(n\) 的所有好排列中,找出一个定点\(^{\text{‡}}\)最少的好排列。如果有多个这样的排列,请打印其中任意一个。

\(\hspace{20px}\)\(^{\text{‡}}\) 排列 \(p\) 的定点是一个索引 \(j\) ( \(1\leq j\leq n\) ),使得 \(p_j = j\) 。

\(\hspace{20px}\)Problem - 2123F - Codeforces

易得出第一个数为 \(1\)。我们可以这么构造数组:分成 \(4\) 组:

我们用一个 \(fa\) 数组存要进行循环的序列,\(d\) 数组存每一个的位置。

Ⅰ质数:\(d[i] = i\)

Ⅱ偶数,但除以二是质数,\(d[i] = i / 2\)

Ⅲ偶数,除以二不是质数,\(d[i] = 2\)

Ⅳ奇数,\(d[i]\) 为第一个质数 \(p\) 使得 \(p | i\)

然后循环时可右移一位,即最后一个第一个输出,其他的从 \(0\) 开始。

点击查看代码
bool isPrime(int n){
    if(n < 2)   return false;
    for(int i = 2;i * i <= n;i++){
        if(n % i == 0)  return false;
    }   return true;
}
void solve(){
    int n;
    cin >> n;
    vector<int> a(n + 1);
    a[1] = 1;
    vector<vector<int>> fa(n + 1);
    vector<int> flag(n + 1, -1); 
    vector<int> d(n + 1);
    for(int i = 2;i <= n;i++){
        if(isPrime(i)){
            fa[i].push_back(i);
            d[i] = i;
        }else{
            if(i % 2 == 0){
                if(isPrime(i / 2)){
                    fa[i / 2].push_back(i);
                    d[i] = i / 2;
                }else{
                    fa[2].push_back(i);
                    d[i] = 2;
                }
            }else{
                for(int j = 3;j <= i;j += 2){
                    if(i % j == 0){
                        fa[j].push_back(i);
                        d[i] = j;
                        break;
                    }
                }
            }
            
        }
    }
    for(int i = 2;i <= n;i++){
        //cout << fa[d[i]].size() << " ";
        if(flag[d[i]] == -1){
            a[i] = fa[d[i]][(int)fa[d[i]].size() - 1];
            fa[d[i]].pop_back();
            flag[d[i]] = 0;
        }else{
            a[i] = fa[d[i]][flag[d[i]]];
            flag[d[i]]++;
        }
        
    }
    for(int i = 1;i <= n;i++){
        cout << a[i] << " ";
    }   cout << "\n";
}

posted on 2025-09-17 10:16  羊毛corn  阅读(14)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3