• [ARC 102F]Revenge of BBuBBBlesort!


    Atcoder ARC 102F

    F:Revenge of BBuBBBlesort!

    题意:

    给你一个长度为(n)的排列(A),可以交换((a_i,a_{i+1},a_{i+2}))当且仅当(a_i>a_{i-1}>a_{i-2}),问(A)是否能经过一系列交换最后有序
    (1 le n le 300000)

    题解:

    emmmm有大佬看错了题,于是就变成了毒瘤题
    真是道神仙题。。看了题解才会,证明容易构造困难啊。
    先构造(B_i=[A_i=i])
    有这个结论
    如果B中有3个连续的0,则没有构造方案((1))
    定义一个序列是合法的,当其01交错且两端是0,特殊地,单独的0,1也是合法的
    我们先极大化每个位置所在合法序列的长度,然后如果对于所有合法序列同时满足以下条件,则存在方案,对于一个([l,r])
    1.其中元素的值域也在([l,r]),要不然换不出去的
    2.对于目标在左边的元素,对于任意的(i < j)满足(a_i < a_j) ((2))
    3.对于目标在右边的元素,对于任意的(i < j)满足(a_i < a_j) ((2))
    以下是口胡的证明:
    ((1)):
    记这三个的位置是((i-1,i,i+1))如果以(i)为中心转了,那么(i)就动不了了,(i-1),(i+1)同理
    ((2)):
    这两个东西原理一样,一起证掉,按目标在左边的考虑
    如果有一个 (i <j),但(a_i > a_j),那么(a_j)一定要跨过(a_i),但这显然不太可能。。

    过程:

    1A

    代码:

    #define GG {puts("No"); return 0;}
    const int N=300010;
    int n;
    int a[N],b[N];
    inline bool Check(int l,int r) {
    	int lbd=0,rbd=0;
    	for(int i=l;i<=r;i++) {
    		if(b[i]<i) {
    			// printf("%d
    ",i);
    			if(lbd>b[i] || (b[i]<l || b[i]>r)) return false;
    			lbd=b[i];
    		} else if(b[i]>i) {
    			if(rbd>b[i] || (b[i]<l || b[i]>r)) return false;
    			rbd=b[i];
    		}
    	}
    	return true;
    }
    signed main() {
    	read(n);
    	for(int i=1;i<=n;i++)
    		read(b[i]),a[i]=(b[i]==i);
    	for(int i=2;i<n;i++) if(!a[i-1] && !a[i] && !a[i+1]) GG
    	for(int i=1;i<=n;i++) {
    		if(a[i]==0) {
    			int now=1;
    			int l=i,r=i;
    			while((a[r]^now) && r<=n) ++r,now^=1;
    			--r;
    			if(!Check(l,r)) GG
    			i=r;
    		}
    	}
    	puts("Yes");
    	return 0;
    }
    

    用时:20min

  • 相关阅读:
    RF基本框架搭建
    Robot Framework连接Oracle数据库
    RF接口测试
    RF-Selenium2Library关键字
    RF-autoit3中有关Send的用法
    RF-selenium2library库
    IPD产品开发流程
    python函数
    python字典
    python元组
  • 原文地址:https://www.cnblogs.com/functionendless/p/9574865.html
Copyright © 2020-2023  润新知