HDU1899 Sum the K-th's(树状数组)

枚举,每次增加点,删除点

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 100008, INF = 0x3F3F3F3F, MOD = 1000000007 ;
#define MS(a, num) memset(a, num, sizeof(a))
int C[N];
int n, m, k;
int a[N], rak[N];

struct data{
    int num, i;
}b[N];
inline int lowbit(int x){
    return x&-x;
}
inline void add(int x, int val){//将第x个数增加val,从1计数
    for(int i=x;i<=n;i+=lowbit(i)){
        C[i] += val;
    }
}
inline int sum(int x){//求1到x的和
    int ret = 0;
    for(int i=x;i>0;i-=lowbit(i)){
        ret+=C[i];
    }
    return ret;
}


bool cmp(const data &a, const data &b){
    return a.num < b.num;
}


int getK(int val){
    int l = 1, r = n + 1;
    while(l < r){
        int m = (l + r)>>1;
        int s = sum(m);
        if(s < k){
            l = m + 1;
        }else{
            r = m;
        }
    }
    return b[l -1].num;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%d %d %d", &n, &m, &k);
        for(int i = 0; i < n; i++){
            scanf("%d", &a[i]);
            b[i].num = a[i];
            b[i].i = i;
        }
        MS(C, 0);
        sort(b, b + n, cmp);

        for(int i = 0; i< n; i++){
            rak[b[i].i] = i + 1;
        }

        LL ans = 0;
        for(int i = 0; i < m; i++){
            add(rak[i % n], 1);
        }

        for(int i = m + 1; i < 2 * m + 1 ;i++){
            add(rak[i % n], 1);
        }

        for(int i = m ; i <= m + n -1 ; i++){
            ans += getK(a[i % n]);
            ans %= MOD;
            if(i != m + n -1 ){
                add(rak[(i - m)%n], -1);
                add(rak[(i + m + 1) % n], 1);
                add(rak[i % n], 1);
                add(rak[(i + 1) % n], -1);
            }
        }
        printf("%I64d ", ans % MOD);
    }
    return 0;

} 

原文地址:https://www.cnblogs.com/IMGavin/p/5708417.html