[HNOI2018] 排列 [贪心]

Author Avatar
空気浮遊 2019年01月03日
  • 在其它设备中阅读本文章
  • 贪心
  • 分享到 Facebook
  • 分享到 Telegram
  • 分享到 Twitter
  • 分享到微博

Problem

题意:第 $i$ 个数一定要放在第 $a_i$ 个数的前面。

Solution

这整个题目都太神奇了。

神奇的题意,神奇的贪心,神奇的计算贡献。

建议去找 pipiboss 的题解,结合 luogu 的第一篇题解查看。

太神奇了。

// Code by ajcxsu
// Problem: permutation

#include<bits/stdc++.h>
using namespace std;

const int N=5e5+10;
typedef long long ll;
struct Node { ll w; int s, id; } nd[N]; 
bool operator <(const Node &a, const Node &b)  {
    return a.w*b.s==b.w*a.s?a.id<b.id:a.w*b.s<b.w*a.s;
}
Node operator +=(Node &a, const Node &b) {
    a.w+=b.w, a.s+=b.s;
    return a;
}
set<Node> s;

int Fa[N];
int Find(int x) { return Fa[x]?Fa[x]=Find(Fa[x]):x; }
bool Union(int a, int b) {
    int af=Find(a), bf=Find(b);
    if(af==bf) return false;
    return Fa[af]=bf, true;
}
int fa[N];
char vis[N];

int h[N], to[N], nexp[N], in[N], p=1;
inline void ins(int a, int b) { nexp[p]=h[a], h[a]=p, to[p]=b, in[b]++, p++; }

int n;
bool topsort() {
    queue<int> qu;
    for(int i=0;i<=n;i++) if(!in[i]) qu.push(i);
    while(!qu.empty()) {
        int na=qu.front(); qu.pop();
        for(int u=h[na];u;u=nexp[u]) {
            in[to[u]]--;
            if(!in[to[u]]) qu.push(to[u]);
        }
    }
    for(int i=0;i<=n;i++) if(in[i]) return false;
    return true;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cin>>n;
    ll w;
    for(int i=1;i<=n;i++) cin>>fa[i], ins(fa[i], i);
    for(int i=1;i<=n;i++) cin>>w, s.insert(nd[i]={w, 1, i});
    if(!topsort()) cout<<-1<<endl, exit(0); // 没找到好的方法判无解。
    Node na;
    ll ans=0;
    nd[0].s=1; // 注意
    while(!s.empty()) {
        na=*s.begin(), s.erase(s.begin());
        fa[na.id]=Find(fa[na.id]);
        if(vis[fa[na.id]]) fa[na.id]=0; // 这个得注意一下
        ans+=nd[fa[na.id]].s*na.w; // 这里是最神奇的。保证在之后加入,又保证与整体时间相匹配。
        if(fa[na.id]) {
            Union(na.id, fa[na.id]);
            s.erase(nd[fa[na.id]]), nd[fa[na.id]]+=na;
            s.insert(nd[fa[na.id]]);
        }
        else vis[na.id]=1, nd[0].s+=na.s; // 注意
    }
    cout<<ans<<endl;
    return 0;
}

本文链接:https://pst.iorinn.moe/archives/sol-hnoi-2018-permutations.html
许可: https://pst.iorinn.moe/license.html
若无特别说明,博客内的文章默认将采用 CC BY 4.0 许可协议 进行许可☆

      新篇
旧篇      
    • fingerprint Login
  • home 主页
  • inbox 归档
    • June 2026 1
    • December 2024 1
    • August 2024 1
    • June 2024 1
    • April 2024 3
    • March 2024 1
    • February 2024 2
    • January 2024 1
    • November 2023 1
    • August 2023 1
    • May 2023 1
    • February 2023 2
    • January 2023 2
    • July 2022 1
    • June 2022 1
    • April 2022 1
    • March 2022 1
    • February 2022 2
    • December 2021 1
    • November 2021 1
    • August 2021 3
    • July 2021 3
    • April 2021 2
    • March 2021 1
    • February 2021 4
    • January 2021 2
    • December 2020 1
    • November 2020 1
    • October 2020 3
    • September 2020 1
    • August 2020 1
    • July 2020 1
    • March 2020 1
    • December 2019 1
    • September 2019 1
    • July 2019 1
    • April 2019 2
    • March 2019 13
    • February 2019 15
    • January 2019 11
    • December 2018 3
    • November 2018 6
    • October 2018 28
    • September 2018 31
    • August 2018 18
    • July 2018 13
    • June 2018 27
    • May 2018 11
    • April 2018 12
    • March 2018 19
    • February 2018 8
    • January 2018 7
    • December 2017 2
    • November 2017 2
  • apps 分类
    • 笔记
    • 题解
    • 杂文
    • 技术
    • 游戏
    • 小说
  • 留言板
  • 关于
  • 友链
  • 文章总数 281
主题 - Material i
expand_less
Copyright © 2026 雪屋
Float in air.
Powered by Typecho
Theme - Material