假设有一列数{Ai}(1<=i<=n),支持如下两种操作
HDU 1166 敌兵布阵
二位树状数组
•1. 将Ai的值加D。
•2. 输出Ai+Ai+1+…+Aj (1<=i<=j<=n)
树状数组是一种特殊的数据结构,这种数据结构的时空复杂度和线段树相似,但是它的系数要小得多HDU 1166 敌兵布阵
题目: A国在海岸线沿直线布置了N个工兵营地。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。
敌兵营地的人数经常变动,大boss每次询问的段都不一样,所以小兵不得不每次都一个一个营地的去数,很快就精疲力尽了
小兵很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?
段都不一样,所以小兵不得不每次都一个一个营地的去数,很快就精疲力尽了小兵很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?
#include<stdio.h>
#include<string.h>
int c[50005],n;
int lowbit(int x)
{
return x&(-x);
}
void add(int i, int val)
{
while(i<=n)
{
c[i]+=val;
i+=lowbit(i);
}
}
void sub(int i, int val)
{
while(i<=n)
{
c[i]-=val;
i+=lowbit(i);
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main()
{
int T, a, b, i, d, time=0;
char ch[10];
scanf("%d", &T);
while(T--)
{
memset(c,0,sizeof(c));
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&d);
add(i,d);
}
while(scanf("%s",ch)&&strcmp(ch,"End")!=0)
{
scanf("%d %d",&a,&b);
if(ch[0]=='Q')
printf("%d\n",sum(b)-sum(a-1));
if(ch[0]=='A')
add(a, b);
if(ch[0]=='S')
sub(a, b);
}
}
return 0;
}
二位树状数组
HLg 2046最后的题目八个字
题目:
给出N*N的矩阵A,初始值为0.进行T次操作,操作有两种:
1>C x1 y1 x2 y2 改变又2点[x1, y1] [x2, y2]确定的矩阵内的值。0变为1, 1变为0
2>Q x y 询问[x,y]点的值为多少
T组输入数据。
每组输入数据第一行2个整数N,M(2 <= N <= 1000, 1 <= M <= 50000)。
接下里的M行代表M次操作:
C x1 y1 x2 y2 (1 <= x1 <= x2 <= N, 1 <= y1 <= y2 <= N) 。
Q x y (1 <= x, y <= N) 。
对于每次的Q操作,输出点(x,y)的值,每个值占一行。
每组数据之后有个换行。
#include<stdio.h>
#include<string.h>
int c[1005][1005],n;
int lowbit(int x)
{
return x&(-x);
}
int sum(int x,int y)
{
int i=y, sum=0;
while(x>0)
{
y=i;
while(y>0)
{
sum+=c[x][y];
y-=Lowbit(y);
}
x-=Lowbit(x);
}
return sum;
}
void add(int x, int y)
{
int i=y;
while(x<=n)
{
y=i;
while(y<=n)
{
c[x][y]++;
y+=Lowbit(y);
}
x+=Lowbit(x);
}
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int T, m, x1, y1, x2, y2, i;
char ch;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m);
memset(c,0,sizeof(c));
getchar();
for(i=0; i<m; i++)
{
scanf("%c",&ch);
if(ch=='C')
{
scanf("%d %d %d %d", &x1,&y1,&x2,&y2);
x2++,y2++;
add(x1,y1,1);
add(x2,y2,1);
add(x1,y2,-1);
add(x2,y1,-1);
}
else
{
scanf("%d %d", &x1,&y1);
printf("%d\n", sum(x1, y1)%2);
}
getchar();
}
puts("");
}
return 0;
}
小兵很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗?