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;
    }
  • 相关阅读:
    case class inheritance
    [Akka]发送一条消息的内部流程
    Java 8 新特性
    大数据学习笔记
    磁盘结构
    AtomicReference 和 volatile 的区别
    How to support both ipv4 and ipv6 address for JAVA code.
    使用JProfiler分析定位java内存泄露memory leak
    redhat mount iso as one yum repository
    Linux Shell常用技巧
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11323926.html
Copyright © 2011-2022 走看看