原题: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;
}