qwb又偷懒了

原题:qwb又偷懒了

原题大意

qwb最近在做一个群众收入统计。ta非常懒,以至于忘记了今天领导要来视察。所以急忙催下属去做统计。
在接下来长度为n的时间里,每个单位时间都有事情发生,可能会发下以下两种事件:

1)下属递交了一份调查报告,由于太匆忙,上面只有一个整数x,代表一个居民的收入。
2)领导来视察了,领导会来询问,收入在区间[l,r]内的居民的平均收入,qwb需要给出回答。

qwb非常讨厌小数,所以qwb上报时都会省略小数部分。如果上报时统计的人数为0,qwb就暴露了他偷懒的事情,他就会zhizhiwuwu。

算法分析

用两个树状数组分别保存收入和人数,坑点在收入为0的情况,可以记录一下0的个数,或者直接平移1。

程序代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const ll maxn = 1000000+100;
ll c1[maxn],c2[maxn];
ll  lowbit(ll x){
    return x & (-x);
}
void update(ll x, ll c[], ll num){
    while(x <= maxn){
        c[x]+=num;
        x+=lowbit(x);
    }
}
ll query(ll x, ll c[]){
    ll sum = 0;
    while(x){
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
void reset(ll x, ll c[]){
    while(x <= maxn){
        c[x] = 0;
        x+=lowbit(x);
    }
}
ll l,r,x;
int n;
int main(){
    while(scanf("%d", &n) != EOF){
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        int t;
        while(n--){
            scanf("%d", &t);
            if(t == 0){
                scanf("%lld", &x);
                x++;
                update(x,c2,x-1);
                update(x,c1,1);
            }
            else{
                scanf("%lld %lld", &l, &r);
                l++,r++;
                ll t1,t2;
                t1 = query(r,c2) - query(l-1,c2);
                t2 = query(r,c1) - query(l-1,c1);
                if(!t2)printf("zhizhiwuwu\n");
                else printf("%lld\n", t1/t2);
            }
        }
/*        reset(1,c1);reset(1,c2);
        c1[0] = c2[0] = 0;*/
       printf("\n");
    }
    return 0;
}