题目链接:http://acm.dlut.edu.cn/problem.php?id=1263
题目思路:树状数组,区间修改,点查询模型,现学现用的=.=,这道题算是树状数组的变形吧。。因为平常树状数组都是用来求和啥的(有很大可能是我孤陋寡闻。。),但这道题是用来进行异或操作的。。所以还得在普通的模板上进行一些小的修改
***********************************************(以下这小部分转自h t t p : / / w w w . c p p b l o g . c o m / m a t o n o 1 / a r c h i v e / 2 0 1 1 / 0 3 / 1 9 / 1 4 2 2 2 6 . h t m l)
或者搜索:树状数组求区间和的一些常见模型,第一个就是。。
(2)“改段求点”型,即对于序列A有以下操作:
【1】修改操作:将A[l..r]之间的全部元素值加上c;
【2】求和操作:求此时A[x]的值。
这个模型中需要设置一个辅助数组B:B[i]表示A[1..i]到目前为止共被整体加了多少(或者可以说成,到目前为止的所有ADD(i, c)操作中c的总和)。
这样就把该模型转化成了“改点求段”型,只是有一点不同的是,SUM(x)不是求B[1..x]的和而是求B[x..N]的和,此时只需把ADD和SUM中的增减次序对调即可(模型1中是ADD加SUM减,这里是ADD减SUM加)。代码:
void
ADD(
int
x,
int
c)
{
for ( int i = x; i > 0 ; i -= i & ( - i)) b[i] += c;
}
int SUM( int x)
{
int s = 0 ;
for ( int i = x; i <= n; i += i & ( - i)) s += b[i];
return s;
}
{
for ( int i = x; i > 0 ; i -= i & ( - i)) b[i] += c;
}
int SUM( int x)
{
int s = 0 ;
for ( int i = x; i <= n; i += i & ( - i)) s += b[i];
return s;
}
操作【1】:ADD(l-1, -c); ADD(r, c);
操作【2】:SUM(x)。
*****************************************************************************
下面是这道题的函数。。。void update(int num,int x)
{
for(int i=num;i>0;i-=lowbit(i))
b[i]=b[i]^x;
}
int ans(int x)
{
int s=0;
for(int i=x;i<=n;i+=lowbit(i))
s=s^b[i];
return s;
}
每次更新的时候,他是把从1-num范围内的所有根节点都进行异或操作(这是第一步操作),最后算相应的值的时候就从当前位置开始,把他所有的祖先对应的值均进行异或操作就可以得出结果。。算了=。=,小松松可是天才,你要是看不懂我写的渣渣文章就自己悟去吧。。。。23333333
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 200000+1;
int num[maxn],b[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(int num,int x)
{
for(int i=num;i>0;i-=lowbit(i))
b[i]=b[i]^x;
}
int ans(int x)
{
int s=0;
for(int i=x;i<=n;i+=lowbit(i))
s=s^b[i];
return s;
}
int main()
{for(int i=7;i>0;i-=lowbit(i))cout<<i<<endl;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(num,0,sizeof(num));
memset(b,0,sizeof(b));
int q;
scanf("%d",&q);
for(int i=0;i<q;i++){
int w,a,b,c;
scanf("%d",&w);
if(w==1){
scanf("%d%d%d",&a,&b,&c);
update(a-1,c);
update(b,c);
}
else{
scanf("%d",&a);
printf("%d\n",ans(a));
}
}printf("\n");
}
return 0;
}