zoukankan      html  css  js  c++  java
  • Gym 100342F Move to Front (树状数组动态维护和查询)

    用树状数组动态和查询修改排名。

    树状数组可以很方便地查询前缀和,那么可以利用这一特点,记录一个点在树状数组里最后一次出现的位置,

    查询出这个位置,就可以知道这个点的排名了。更改这个点的排名的时候只要把原来位置修改成0,然后在新的位置加上1就行了。

    把询问离线,数据范围比较大,先用快排+去重离散(用map也可,就是慢了一点),

     

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5+5, N = maxn*2-1;
    
    int a[maxn],q[maxn],C[N+1],sz,pos[maxn];
    
    #define lowbit(x) ((x)&-(x))
    
    void add(int x,int d)
    {
        while(x<N){
            C[x] += d; x += lowbit(x);
        }
    }
    
    int sum(int x)
    {
        int ret = 0;
        while(x>0){
            ret += C[x]; x -= lowbit(x);
        }
        return ret;
    }
    
    int b_search(int val,int *A = a,int l = 0,int r = sz)
    {
        int m;
        while(l<r){
            m = (l+r)>>1;
            if(val>A[m]) l = m+1;
            else if(val<A[m]) r = m;
            else return m;
        }
        return -1;
    }
    
    int main()
    {
        freopen("mtf.in","r",stdin);
        freopen("mtf.out","w",stdout);
        int n; cin>>n;
        for(int i = 0; i < n; i++) scanf("%d",a+i),q[i]=a[i];
        sort(a,a+n);
        sz = unique(a,a+n)-a;
        for(int i = 0; i < sz; i++){
            add(pos[i] = maxn+i,1);
        }
        int cur = maxn-1;
        for(int i = 0; i < n; i++){
            int x = b_search(q[i]), ans;
            if(pos[x] == maxn+x) ans = sum(pos[x]) - x-1 + q[i];
            else ans = sum(pos[x]);
            printf("%d%c",ans,i==n-1?'
    ':' ');
            add(pos[x],-1);
            add(pos[x] = cur--,1);
        }
        return 0;
    }
  • 相关阅读:
    使用Doxygen生成net帮助文档
    Mac OSX 下配置 LNMP开发环境
    vue相关网站资源收集
    AJAX 相关笔记
    toLocaleDateString()
    前端关于图片的优化
    css 水平垂直居中的方法总结
    Mac下安装Twig模版引擎的方法
    gulp基础使用总结
    js中元素操作的有关内容与对比
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4771114.html
Copyright © 2011-2022 走看看