zoukankan      html  css  js  c++  java
  • ARC102D Revenge of BBuBBBlesort!

    Link
    首先发现一次操作相当于交换两个距离为(1)的数。
    那么如果奇数位上有偶数或者偶数位上有奇数,一定就是不合法的。
    注意到对原排列进行一次操作,会让逆序对数减少(3)
    我们把奇数位和偶数位分成两个排列,那么对原排列进行一次操作,会让这两个排列中的某个排列的逆序对数减少(1)
    因此第二个必要条件是原排列的逆序对数为奇数偶数位分开后的两个排列的逆序对数之和的(3)倍。
    然后我们证明这也是充分条件。
    考虑对分开后的两个排列冒泡排序,每次这两个排列中的某一个逆序对数会减少(3)
    而对于原排列,逆序对数会减少不超过(3)。并且如果逆序对数减少了(3),那么这一定是一个合法的操作。
    由第二个条件可知每次操作都是合法的,因此如果满足了第一个条件,那么这个排列就是合法的。

    #include<cstdio>
    #include<vector>
    #include<cstring>
    using i64=long long;
    int n,flg=1,t[300007];std::vector<int>p[3];
    int read(){int x;scanf("%d",&x);return x;}
    void add(int p){while(p)++t[p],p^=p&-p;}
    int ask(int p){int r=0;while(p<=n)r+=t[p],p+=p&-p;return r;}
    i64 tao(std::vector<int>p){i64 r=0;memset(t,0,sizeof t);for(int x:p)r+=ask(x),add(x);return r;}
    int main()
    {
        n=read();
        for(int i=1,x;i<=n;++i) p[2].push_back(x=read()),p[i&1].push_back(x),flg&=!((i^x)&1);
        puts(flg&(tao(p[2])==3*(tao(p[0])+tao(p[1])))? "Yes":"No");
    }
    
  • 相关阅读:
    信息系统项目管理师沟通的四个好习惯
    Android 线程
    替换exe程序图标DLL
    Python 邮件类
    android自适应屏幕方向和大小
    sqlserver 存储过程
    FinalData 数据恢复工具[绿色版]
    Python Python 正则 取中括号值
    在Button任意位置加图片效果
    android GPRS
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12458076.html
Copyright © 2011-2022 走看看