bzoj 4397: [Usaco2015 dec]Breed Counting 前缀和/线段树

#include<iostream>
#include<cstdio>

using namespace std;

int n,m;
int sum1[100010],sum2[100010],sum3[100010];

int main(){
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++){
int x;
scanf("%d",&x);
if(x==1)sum1[i]=1;
if(x==2)sum2[i]=1;
if(x==3)sum3[i]=1;
sum1[i]+=sum1[i-1];
sum2[i]+=sum2[i-1];
sum3[i]+=sum3[i-1];
}
while(m--){
int x,y;
scanf("%d%d",&x,&y);
printf("%d %d %d\n",sum1[y]-sum1[x-1],sum2[y]-sum2[x-1],sum3[y]-sum3[x-1]);
}

return 0;
}

#include<iostream>
#include<cstdio>

using namespace std;

struct node{
int l,r;
int num1,num2,num3;
}tree[400040];

int n,m;
int ans1,ans2,ans3;

void build(int x,int l,int r){
tree[x].l=l;
tree[x].r=r;
if(l==r){
int y;
scanf("%d",&y);
if(y==1)tree[x].num1=1;
else if(y==2)tree[x].num2=1;
else tree[x].num3=1;
return;
}
int mid=(l+r)/2;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
tree[x].num1=tree[x*2].num1+tree[x*2+1].num1;
tree[x].num2=tree[x*2].num2+tree[x*2+1].num2;
tree[x].num3=tree[x*2].num3+tree[x*2+1].num3;

return;
}

void chaxun(int x,int l,int r){
if(tree[x].r<l || tree[x].l>r)return;
if(tree[x].l>=l && tree[x].r<=r){
ans1+=tree[x].num1;
ans2+=tree[x].num2;
ans3+=tree[x].num3;
return;
}
int mid=(tree[x].l+tree[x].r)/2;
if(mid<l)chaxun(x*2+1,l,r);
else if(mid>=r)chaxun(x*2,l,r);
else chaxun(x*2,l,r),chaxun(x*2+1,l,r);

return;
}

int main(){
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
ans1=ans2=ans3=0;
chaxun(1,x,y);
printf("%d %d %d\n",ans1,ans2,ans3);
}

return 0;
}