我最近阅读了关于 2D二进制索引树 的内容 ( http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees )
为了解决Codeforces的问题,
( http://codeforces.com/problemset/problem/341/D )
可以看出,该问题在2维固定大小数组上查找混合更新和读取操作。
在实现 2D BIT 的功能时,我自己实现了读取功能,并在Topcoder上找到了更新功能。
在读取功能中,我已将扩展名应用于 1D BIT ,方法是在该点读取树(责任人)以获得(1,1) uptil (x,y),然后为了删除不需要的值,我重复 XOR 矩形部分值我不需要为了消除它们。
我读到的选区1中的区域是子矩形(1,1,x1,y1),然后我 XOR 所有值都在两个子矩形(1,1,x0-1,y1)和(1,1,x1,y0-1)中。 2个子矩形本身正在进行读操作。然后由于子矩形(1,1,x0-1,y0-1)是 XORed 奇数次,我对最终读取操作的结果为(1,1,x0-1,y0-1)。根据我这应该是解决这个问题的标准方法。我在哪里踌躇不前,更重要的是我是否错误地实施了任何功能?
请注意任何错误,因为我没有取得任何进展。
P.S。:当我显示树[] []时,它显示正确,我不知道为什么报告的答案不正确。
我的解决方案(在ideone处)的链接是: http://ideone.com/vJIxHZ
附加的代码是:
#include <bits/stdc++.h>
#define ll long long int
ll tree[1002][1002];
using namespace std;
ll read(ll x,ll y,ll n)
{
ll sum=0;
while(x>0 )
{
ll y1=y;
while(y1>0)
{
sum ^= tree[x][y1];
y1-=(y1&-y1);
}
x-=(x&-x);
}
return sum;
}
void update(ll x , ll y , ll val, ll n){
ll y1;
while (x <= n){
y1 = y;
while (y1 <= n){
tree[x][y1] ^= val;
y1 += (y1 & -y1);
}
x += (x & -x);
}
}
int main() {
// your code goes here
#define int long long int
int n,m,x0,y0,x1,y1,v;
//scanf("%I64d%I64d",&n,&m);
cin>>n>>m;
/* for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
{
tree[i][j]=0;
} */
while(m--)
{
int choice;
//scanf("%I64d",&choice);
cin>>choice;
if(choice==1)
{
//scanf("%I64d%I64d%I64d%I64d",&x0,&y0,&x1,&y1);
cin>>x0>>y0>>x1>>y1;
cout<<(read(x1,y1,n)^read(x0-1,y1,n)^read(x1,y0-1,n)^read(x0-1,y0-1,n))<<"\n";
//printf("%I64d\n",
}
else
{
// scanf("%I64d%I64d%I64d%I64d%I64d",&x0,&y0,&x1,&y1,&v);
cin>>x0>>y0>>x1>>y1>>v;
update(x0,y0,v,n);
update(x0,y1+1,v,n);
update(x1+1,y0,v,n);
update(x1+1,y1+1,v,n);
}
}
/* for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
cout<<read(i,j,n)<<" ";
}
cout<<"\n";
} */
return 0;
}