zoukankan      html  css  js  c++  java
  • LOJ#6130. 「2017 山东三轮集训 Day1」Fable 树状数组+逆序对

    求:对一个数列进行 $k$ 次冒泡排序后的结果.    

    先考虑数字互不相同的情况.    

    设 $i$ 位置前大于 $v[i]$ 的数字有 $ma[i]$ 个.    

    那么,如果 $k leqslant ma[i]$,则 $i$ 位置的数就会移到 $i-k$.       

    否则,$i$ 位置的数就会向前移动 $ma[i]$ 次后成为前缀最大值,然后开始向后移动.        

    对于能确定位置的数字设成第一类,不能确定的设成第二类,那么我们只需确定所有第二类数的位置即可.     

    对于第二类数字 $x$ 来说,其肯定会在 ma[i] 时刻成为前缀最大值.       

    然后这个数字就会一直向后移动.    

    而这个数字要是向后移动的话只可能是后面小于该数的数字移动到该数字前面来.    

    所以如果一个数在第二类数中成为前缀最大值,该数在第二类数中就始终是前缀最大值.   

    也就是说,对于第二类数字,不会出现大的出现在小的前面.           

    那么我们就将第二类数字排序,依次放到空白位置即可.  

    然后如果有相同数字的话就让前面的数小于后面的数(这样相同的数就不会交换了)  

    #include <set>  
    #include <cstdio> 
    #include <algorithm> 
    #define N 200009   
    #define ll long long   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;   
    int n,K;  
    int a[N],A[N],bu[N],arr[N],id[N],sum[N],pos[N];      
    int lowbit(int x) { return x&(-x); }    
    void update(int x,int v) {  
        for(;x<N;x+=lowbit(x))  
            sum[x]+=v;  
    }  
    int query(int x) { 
        int re=0; 
        for(;x;x-=lowbit(x))  
            re+=sum[x];  
        return re;   
    }      
    set<int>se;  
    set<int>::iterator it;  
    int main() {  
        // setIO("input");  
        // freopen("input.out","w",stdout);  
        scanf("%d%d",&n,&K);   
        for(int i=1;i<=n;++i) {  
            scanf("%d",&a[i]);   
            A[i]=a[i];     
        }
        sort(A+1,A+1+n);  
        for(int i=1;i<=n;++i) {  
            a[i]=lower_bound(A+1,A+1+n,a[i])-A;     
        }                   
        for(int i=1;i<=n;++i) {    
            if(!bu[a[i]]) {  
                bu[a[i]]=a[i];     
            }      
            else ++bu[a[i]];   
            arr[i]=bu[a[i]];    
            id[arr[i]]=A[a[i]];  
        }        
        for(int i=1;i<=n;++i) {     
            int num=i-1-query(arr[i]);              
            if(K<=num) {     
                pos[i-K]=arr[i];  
            }      
            else { 
                se.insert(arr[i]);  
            }
            update(arr[i],1);  
        }
        for(int i=1;i<=n;++i) { 
            if(pos[i]) printf("%d
    ",id[pos[i]]);   
            else {   
                it=se.begin();  
                printf("%d
    ",id[*it]);   
                se.erase(it);  
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    12.浏览器测试
    11.测试用例管理
    10.测试用例的钩子
    如何处理JSON中的特殊字符
    foreach的参数不是数组:Warning: Invalid argument supplied for foreach
    CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写
    CodeIgniter配置之config
    **Apache Options指令详解
    .htaccess的基本作用及相关语法介绍
    .htaccess文件的作用(访问控制)
  • 原文地址:https://www.cnblogs.com/guangheli/p/13293177.html
Copyright © 2011-2022 走看看