《hdu6534》

比赛的时候一直想的主席树,维护的复杂度已经够了,但是插入又不对了。

最后就卡死了。

莫队老是想不到,太菜了。

正解:莫队离线一下询问。我们从左向右维护点的值。

那么加上每个点的代价,查询一下区间内[a[i] - k,a[i] + k]的个数即可。

减去每个点同理,但是因为自己也会被算在内。所以减去的时候,要先删掉自己的值再算,因为我们加上的时候其实是没有算上自己的代价的。

然后这题线段树会T,所以要树状数组维护区间和。

《hdu6534》
// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 27005;
const int M = 2e5 + 5;
const double eps = 1e-10;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline int read() {
    int f = 1;int x = 0;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
inline long long ADD(long long x,long long y) {return (x + y) % Mod;}
inline long long DEC(long long x,long long y) {return (x - y + Mod) % Mod;}
inline long long MUL(long long x,long long y) {return x * y % Mod;}

int a[N],b[N * 3],ans[N],len = 0,k,L[N],r[N],ps[N],n;
struct Query{int L,r,bl,id;}p[N];
LL ma = 0;
bool cmp(Query a,Query b) {
    if(a.bl != b.bl) return a.L < b.L;
    if(a.bl&1) return a.r < b.r;
    return a.r > b.r;
}
int lowbit(int x) {return x & (-x);}
int sum[N * 3];
void add_num(int x,int val) {
    for(int i = x;i <= len;i += lowbit(i)) sum[i] += val;
}
int query2(int x) {
    int tmp = 0;
    for(int i = x;i;i -= lowbit(i)) tmp += sum[i];
    return tmp;
}
int query(int L,int r) {
    return query2(r) - query2(L - 1);
} 
void del(int x) {
    add_num(ps[x],-1);
    int sum = query(L[x],r[x]);
    ma -= sum;
}
void add(int x) {
    int sum = query(L[x],r[x]);
    ma += sum;
    add_num(ps[x],1);
}
void solve() { 
    int m;n = read(),m = read(),k = read();
    for(int i = 1;i <= n;++i) {
        a[i] = read();
        b[++len] = a[i] + k;
        b[++len] = a[i] - k;
        b[++len] = a[i];
    }
    sort(b + 1,b + len + 1);
    len = unique(b + 1,b + len + 1) - b - 1;
    for(int i = 1;i <= n;++i) {
        L[i] = lower_bound(b + 1,b + len + 1,a[i] - k) - b;
        r[i] = lower_bound(b + 1,b + len + 1,a[i] + k) - b;
        ps[i] = lower_bound(b + 1,b + len + 1,a[i]) - b;
    }
    int blsize = sqrt(n);
    for(int i = 1;i <= m;++i) p[i].L = read(),p[i].r = read(),p[i].id = i,p[i].bl = (p[i].L - 1) / blsize + 1;
    sort(p + 1,p + m + 1,cmp);
    int L = 1,r = 0;
    for(int i = 1;i <= m;++i) {
        while(L < p[i].L) del(L++);
        while(L > p[i].L) add(--L);
        while(r < p[i].r) add(++r);
        while(r > p[i].r) del(r--);
        ans[p[i].id] = ma;
    }
    for(int i = 1;i <= m;++i) printf("%d\n",ans[i]);
} 
int main() {    
    solve();
    system("pause");
    return 0;
}
View Code

 

上一篇:使用group by对数据进行汇总计算


下一篇:什么让python-pandas与excel彻底拉开了距离