您的位置:首页 > 其它

HDU 1166

2015-09-21 21:18 239 查看
HDU 1166 树状数组

传送门

题意自己看了,不想描述了。

解题思路:这是典型的单点更新问题,解法一般用线段树,但这道题问题比较简单,能用树状数组解决,而且效率比线段树快很多。

树状数组的精要之处就是

int lowbit(int x)
{
return x&-x;
}


至于为什么精要,请自学原码,反码,补码,以及二进制思想。如果你精通了以上的东西,你就会发现上面的lowbit函数简直惊为天人所做,智商直接被碾压至死,而且描述如此简洁,堪称艺术。

回归正题,此题就是单纯的考单点更新,所以直接上lowbit,读数的时候注意一下就行了。

有个坑,就是输出”Case i:\n”时,要在最前面输出,就是读完数组后就输出,如果放在while循环里,会WA…………

还有就是单写一个lowbit函数效率比较低,所以直接写到函数里,具体见代码。

#include<stdio.h>
#include<string.h>
int t,d[50005],num,n,cas;
char s[10];
void UP(int x,int num)
{
while(x<=n)
{
d[x]+=num;
x+=(x&-x);
}
}
int sum(int x,int y)
{
int s=0;
for(;x>0||y>0;x-=(x&-x),y-=(y&-y))
{
if(x>0)s+=d[x];
if(y>0)s-=d[y];
}
return s;
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(d,0,sizeof(d));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
UP(i,num);
}
printf("Case %d:\n",++cas);
while(scanf("%s",s),s[0]!='E')
{
int x,y;
scanf("%d%d",&x,&y);
if(s[0]=='Q')printf("%d\n",sum(y,x-1));
else if(s[0]=='A')UP(x,y);
else UP(x,-y);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树状数组