• AGC001F Wide Swap


    Link
    首先进行一个转换,我们构造(q)使得(q_{p_i}=i),那么最小化(p)的字典序实质上就是最小化(q)的字典序。
    然后题目给的限制就变成了只能交换(q_i,q_{i+1}(|q_i-q_{i+1}|le k)),等价于满足(|q_i-q_j|le k(i<j))(q_i,q_j)的相对位置不变。
    这样我们就可以(q_i ightarrow q_j)表示(q_i)必须在(q_j)前面,然后求最小拓扑序。
    直接建边是(O(n^2))的,我们可以对每个(q_i),只向(j>i)(q_jin[q_i-k+1,q_i-1])(q_jin[q_i+1,q_i+k-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('
    ');}
    }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;
    }
    
  • 相关阅读:
    NGINX反向代理与负载均衡
    kubernetes介绍
    Linux下yum出现no module named pycurl 解决办法
    MySQL中间件介绍
    Memcached做Tomcat的session共享
    MySQL高负载优化
    Centos下安装Tomcat7
    浅谈世界坐标系,相机坐标系,图像坐标系,像素坐标系的关系
    相机标定方法之初探
    ubuntu18.04安装kalibr相机标定工具
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12233486.html
Copyright © 2020-2023  润新知