码迷,mamicode.com
首页 > 其他好文 > 详细

Gym 100342F Move to Front

时间:2015-08-30 17:11:46      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

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

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

查询出这个位置,就可以知道这个点的排名了。更改这个点的排名的时候只要把原来位置修改成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; //cout<<x<<endl;
        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?\n: );
        add(pos[x],-1);
        add(pos[x] = cur--,1);
    }
    return 0;
}

 

Gym 100342F Move to Front

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4771114.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!