[Explanations] AT1984 Wide Swap (topological sorting)

[Explanations] AT1984 Wide Swap (topological sorting)

Permutation Problem routine consideration of a large array of arc (arc [data [t]] = t)

Then swap the nature of the subject, is converted to an array value adjacent to the arc, if the difference is greater than equal to \ (K \) may be exchanged, or can not.

Consider the arc array of any two numbers \ (x, y \) condition (assuming the position of x <y position) can be exchanged, with the proviso that in \ (x, y \) between absence and their difference is less than \ (k \) numbers. But if so, then \ (x, y \) can never be exchanged. In other words, the final answer, the location is \ (x \) number will be less than the position \ (y \) number.

"Must be smaller than" relation will form a DAG, if a predetermined \ (y-> x \) represents \ (X \) smaller than a certain number on a position of y. All programs meet the DAG are legitimate programs. A legitimate program algorithm is generated in this topology DAG by peeling one point, and to assign reference numerals incremented when the stripping point, which is equivalent to give a topological order, such that the first and \ (\ 1) small dots as much as possible by before, then meet second-largest far forward as possible ... it becomes a HNOI dishes produced.

Considering the complexity of the problem, violence \ (O (n ^ 2) \) enumeration does not work, can be found if \ (x, y \) can not exchange and \ (y, z \) can not be exchanged, then the \ (X, Z \) can not exchange (z position is greater than the y position), so long as the connection at the smallest y index on the line.

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>

using namespace std;  typedef long long ll;
inline int qr(){
    int ret=0,f=0,c=getchar();
    while(!isdigit(c))f|=c==45,c=getchar();
    while(isdigit(c)) ret=ret*10+c-48,c=getchar();
    return f?-ret:ret;
}

const int maxn=5e5+5;
const int inf=0x3f3f3f3f;
vector<int> e[maxn];
int data[maxn],arc[maxn],dr[maxn],n,k;
int seg[maxn<<2],ans[maxn];
void pp(int pos){seg[pos]=min(seg[pos<<1],seg[pos<<1|1]);}
void add(int fr,int to){e[to].push_back(fr);++dr[fr];}

#define mid ((l+r)>>1)
#define lef l,mid,pos<<1
#define rgt mid+1,r,pos<<1|1
int que(int L,int R,int l,int r,int pos){
    if(L>r||R<l) return inf;
    if(L<=l&&r<=R) return seg[pos];
    return min(que(L,R,lef),que(L,R,rgt));
}
void upd(int p,int v,int l,int r,int pos){
    if(p<l||p>r) return;
    if(l==r) return seg[pos]=v,void();
    upd(p,v,lef); upd(p,v,rgt);
    pp(pos);
}
#undef mid
#undef lef
#undef rgt

int main(){
    n=qr(); k=qr();
    for(int t=1;t<=n;++t) data[t]=qr(),arc[data[t]]=t;
    memset(seg,0x3f,sizeof seg);
    for(int t=n;t;--t){
        int t1=que(arc[t]-k+1,arc[t]-1,1,n,1);
        int t2=que(arc[t]+1,arc[t]+k-1,1,n,1);
        if(t1<=n) add(arc[t],arc[t1]);
        if(t2<=n) add(arc[t],arc[t2]);
        upd(arc[t],t,1,n,1);
    }
    static priority_queue<int> q;
    for(int t=1;t<=n;++t)
        if(!dr[t]) q.push(t);
    int cnt=0;
    while(q.size()){
        int now=q.top();
        ans[now]=++cnt;
        q.pop();
        for(auto t:e[now])
            if(--dr[t]==0)
                q.push(t);
    }
    for(int t=1;t<=n;++t) printf("%d\n",n-ans[t]+1);
    return 0;
}

Guess you like

Origin www.cnblogs.com/winlere/p/12241542.html