AGC001F Wide Swap

Link
first performed a conversion, we construct \ (Q \) such that \ (Q_ P_i} = {I \) , then the minimum of \ (P \) lexicographic order is substantially minimized \ (Q \) lexicographic order.
Then subject to only limited exchange becomes \ (Q_I, Q_. 1} + I {(| Q_I-Q_ +. 1 {I} | \ Le K) \) , equivalent to satisfy \ (| q_i-q_j | \ le k (i <j ) \) a \ (q_i, q_j \) relative positions unchanged.
So that we can \ (q_i \ rightarrow q_j \) represents \ (q_i \) must (q_j \) \ in front, and then find the smallest topological order.
Edge is built directly \ (O (n ^ 2) \) , we can for each \ (Q_I \) , only the \ (j> i \) a \ (q_j \ in [q_i- k + 1, q_i -1] \) and \ (q_j \ in [q_i + 1, q_i + k-1] \) in the latest two even sides, so that even the sides of the apparent partial order is not affected.
Specifically, you can do back to front, with maintenance tree line just fine.

#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<functional>
namespace IO
{
    char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
    void Put(char x){*oS++=x;if(oS==oT)Flush();}
    int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
    void write(int x){int top=0;while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('\n');}
}using namespace IO;
using std::vector;
using std::priority_queue;
int min(int a,int b){return a<b? a:b;}
const int N=500007,inf=0x7f7f7f7f;
vector<int>e[N];priority_queue<int,vector<int>,std::greater<int>>Q;
int n,k,p[N],q[N],mn[N<<2],deg[N];
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
void pushup(int p){mn[p]=min(mn[ls],mn[rs]);}
void update(int p,int l,int r,int x,int v)
{
    if(r==l) return (void)(mn[p]=v);
    (x<=mid? update(ls,l,mid,x,v):update(rs,mid+1,r,x,v)),pushup(p);
}
int query(int p,int l,int r,int L,int R)
{
    if(r<L||R<l) return inf;
    if(L<=l&&r<=R) return mn[p];
    return min(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R));
}
int main()
{
    int n=read(),k=read(),m=0;memset(mn,0x7f,sizeof mn);
    for(int i=1;i<=n;++i) q[read()]=i;
    for(int i=n,j;i;--i)
    {
    if((j=query(1,1,n,q[i]+1,q[i]+k-1))^inf) ++deg[q[j]],e[q[i]].push_back(q[j]);
    if((j=query(1,1,n,q[i]-k+1,q[i]-1))^inf) ++deg[q[j]],e[q[i]].push_back(q[j]);
    update(1,1,n,q[i],i);
    }
    for(int i=1;i<=n;++i) if(!deg[i]) Q.push(i);
    for(int u;!Q.empty();)
    {
    q[++m]=u=Q.top(),Q.pop();
    for(int v:e[u]) if(!--deg[v]) Q.push(v);
    }
    for(int i=1;i<=n;++i) p[q[i]]=i;
    for(int i=1;i<=n;++i) write(p[i]);
    return Flush(),0;
}

Guess you like

Origin www.cnblogs.com/cjoierShiina-Mashiro/p/12233486.html