zoukankan      html  css  js  c++  java
  • 【agc001F】Wide Swap

    神仙题啊。

    题面

    https://www.luogu.org/problem/AT1984

    题解

    首先对序列求逆,变成相邻两个如果差大于等于$k$则可交换。

    如果小于$k$,那相对位置永远不会发生变化,连一条有向边。

    原序列字典序最小,就是逆序列的反序列字典序最大(见“菜肴制作”)

    建反边,用大根堆(普通的$priority queue<int>$)拓扑排序,再反过来。

    都是这样边数是$O(n^2)$的,考虑优化,每个点只向值域内最近的第一个大于自己的和第一个小于自己的连边,用一个扫描线$+ set$实现。

    #include<set>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 500500
    #define ri register int
    using namespace std;
    
    int n,k;
    int a[N],p[N],ans[N],ans2[N],ru[N];
    
    set<int> s;
    vector<int> to[N];
    priority_queue<int> pq;
    
    void add_edge(int u,int v) {
      to[v].push_back(u); ru[u]++;
    }
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    int main() {
      n=read(); k=read();
      for (ri i=1;i<=n;i++) a[p[i]=read()]=i;
      
      for (ri i=1;i<=n+k-1;i++) {
        if (i<=n) s.insert(p[i]);
        if (i-k+1>=1) s.erase(p[i-k+1]);
        if (i+1<=n) {
          set<int> ::  iterator cur=s.upper_bound(p[i+1]);
          if (cur!=s.end()) add_edge(i+1,a[*cur]);
        }
        if (i-k+1>=1) {
          set<int> :: iterator cur=s.upper_bound(p[i-k+1]);
          if (cur!=s.end()) add_edge(i-k+1,a[*cur]);
        }
      }
      
      for (ri i=1;i<=n;i++) if (!ru[i]) pq.push(i);
      int cc=0;
      while (!pq.empty()) {
        int x=pq.top(); pq.pop();
        ans[++cc]=x;
        for (ri i=0;i<to[x].size();i++) {
          int y=to[x][i];
          ru[y]--;
          if (!ru[y]) pq.push(y);
        }
      }
      
      for (ri i=1;i<=n;i++) ans2[ans[n-i+1]]=i;
      for (ri i=1;i<=n;i++) printf("%d
    ",ans2[i]);
      return 0;
    }
  • 相关阅读:
    Prim+堆优化
    Tarjan缩点+建新图
    CF482A
    CF545C
    CF570B
    Python 入门2 list介绍
    Python 入门1 上传代码
    黑客与画家 第十三章
    黑客与画家 第十一章
    黑客与画家 第五章
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11323926.html
Copyright © 2011-2022 走看看