二维插点,求区间:
4(sum(x2,y2) + 1(sum(x1-1,y1-1))- 2(sum(x1-1,y2))-3(sum(x2,y1-1)))
http://poj.org/problem?id=1195
分析:裸二维树状数组
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int NM=1030;
__int64 a[NM][NM];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y,int t)
{
for(int i=x;i<NM;i+=lowbit(i))
for(int j=y;j<NM;j+=lowbit(j))
{
if(a[i][j]+t<0) a[i][j]=0; //
else a[i][j]+=t;
}
}
__int64 sum(int x,int y)
{
__int64 ans=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
ans+=a[i][j];
return ans;
}
int main()
{
int x1,y1,x2,y2,t,n,temp;
scanf("%d%d",&t,&n);
while(scanf("%d",&t))
{
if(t==3) break;
else if(t==1)
{
scanf("%d%d%d",&x1,&y1,&temp);
x1++,y1++;
add(x1,y1,temp);
}
else if(t==2)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1++,y1++,x2++,y2++;
printf("%I64d\n",sum(x2,y2)+sum(x1-1,y1-1)-sum(x1-1,y2)-sum(x2,y1-1));
}
}
return 0;
}
http://acm.hdu.edu.cn/showproblem.php?pid=2642
分析:裸二维树状数组
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int NM=1005;
int a[NM][NM];
bool f[NM][NM];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y,int t)
{
for(int i=x;i<NM;i+=lowbit(i))
for(int j=y;j<NM;j+=lowbit(j))
a[i][j]+=t;
}
int sum(int x,int y) //从1开始算
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
ans+=a[i][j];
return ans;
}
int main()
{
int x1,y1,x2,y2,x,y,T;
char cc[5];
while(scanf("%d",&T)!=EOF)
{
memset(f,0,sizeof(f)); //开始时灯都是灭的
memset(a,0,sizeof(a));
while(T--)
{
scanf("%s",cc);
if(cc[0]=='D')
{
scanf("%d%d",&x,&y);
x++,y++;
if(!f[x][y]) continue;
f[x][y]=false;
add(x,y,-1);
}
else if(cc[0]=='B') //bright
{
scanf("%d%d",&x,&y);
x++,y++;
if(f[x][y]) continue;
f[x][y]=true;
add(x,y,1);
}
else
{
scanf("%d%d%d%d",&x1,&x2,&y1,&y2);
x1++,y1++,x2++,y2++;
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
//注意边界
printf("%d\n",sum(x2,y2)+sum(x1-1,y1-1)-sum(x2,y1-1)-sum(x1-1,y2));
}
}
}
return 0;
}