hdu 1166(树状数组 或 线段树)

时间:2023-03-08 18:53:13
hdu 1166(树状数组 或 线段树)

线段树 (本题无需建树,少了很多)

#include<cstdio>
#include<cstring>
int sum[5000005],rt,data,lb,rb,n,m;
void add(int p,int l,int r,int now)//data新加的数 第p个位置 第now个子树
{
sum[now]+=data;
if(l==r) return;
int mid=(l+r)/2;
if(p<=mid) add(p,l,mid,2*now);
else add(p,mid+1,r,2*now+1);
}
int query(int l,int r,int now)
{
int mid=(l+r)/2;
if(lb<=l&&rb>=r) return(sum[now]);
if(rb<=mid) return(query(l,mid,2*now));
else if(lb>mid) return(query(mid+1,r,2*now+1));
else return(query(l,mid,2*now)+query(mid+1,r,2*now+1));
}
int main()
{
int t,tt,i,j;
char s[100];
scanf("%d",&t);
for(tt=1;tt<=t;tt++){
scanf("%d",&n);
printf("Case %d:\n",tt);
memset(sum,0,sizeof(sum));
for(i=1;i<=n;i++){
scanf("%d",&data);
add(i,1,n,1);
}
while(1){
scanf("%s",&s);
if(s[0]=='E') break; else scanf("%d%d",&i,&j);
switch(s[0]){
case 'A':data=j;add(i,1,n,1);break;
case 'S':data=-j;add(i,1,n,1);break;
case 'Q':lb=i;rb=j;printf("%d\n",query(1,n,1));break;
}
}
}
return 0;
}

简单的树状数组

先给个经典图片

hdu 1166(树状数组 或 线段树)

#include<iostream>
#include<cstdio>
#include<cstring>
int n,a[50005];
int lowbit(int a)
{
return(a&(-a));
}
void add(int p,int q)
{
for(int i=q;i<=n;i+=lowbit(i))
a[i]+=p;
}
int sum(int q)
{
int ans=0;
for(int i=q;i>0;i-=lowbit(i))
ans+=a[i];
return(ans);
}
int main()
{
int t,tt,i,j,k;
char s[100];
scanf("%d",&t);
for(tt=1;tt<=t;tt++){
scanf("%d",&n);
printf("Case %d:\n",tt);
memset(a,0,sizeof(a));
for(i=1;i<=n;i++){
scanf("%d",&k);
add(k,i);
}
while(1){
scanf("%s",&s);
if(s[0]=='E') break; else scanf("%d%d",&i,&j);
switch(s[0]){
case 'A':add(j,i);break;
case 'S':add(-j,i);break;
case 'Q':printf("%d\n",sum(j)-sum(i-1));break;
}
}
}
return 0;
}