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;
    }
  • 相关阅读:
    常用正则表达式
    java中的异或运算
    Eclipse 中,web项目在Tomcat运行时填写不了Server name
    错误: 找不到或无法加载主类 tomcat-juli.jar
    Hadoop学习之Ubuntu12.04 Hadoop 环境搭建笔记
    ubuntu安装 cober 笔记
    Ubuntu中安装JDK
    对象调用很容易忽视的地址问题
    2018.09.27_练习时的tips
    网页的组成(一)
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4771114.html
Copyright © 2011-2022 走看看