AGC001F Wide Своп

Ссылка
первой выполняется преобразование, мы строим \ (Q \) такое , что \ (Q_ P_i} = {Я \) , то минимум \ (Р \) лексикографический порядок, по существу сведен к минимуму \ (Q \) лексикографический порядок.
Тогда при условии ограниченной только обмен становится \ (q_i, Q_ 1} + I {(| q_i-Q_ + 1 {I.} |. \ Le K) \) , что эквивалентно удовлетворяют \ (| q_i-q_j | \ ле к (я <у ) \) \ (q_i, q_j \) относительные позиции без изменений.
Так что мы можем \ (q_i \ СтрелкаВправо q_j \) представляет \ (q_i \) обязательно (q_j \) \ в передней, а затем найти наименьший топологический порядок.
Край построен непосредственно \ (O (N ^ 2) \) , мы можем для каждого \ (q_i \) , только \ (J> Я \) в \ (\ q_j в [q_i- к + 1, q_i -1] \) и \ (q_j \ в [q_i + 1, q_i + к-1] \) в последних двух четных сторон, так что даже боковые стороны видимого частичного порядка не затрагивается.
В частности, вы можете сделать задом наперед, с линией обслуживания дерева просто отлично.

#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;
}

рекомендация

отwww.cnblogs.com/cjoierShiina-Mashiro/p/12233486.html