问题描述
zxa最近对按位异或(exclusive disjunction)产生了极大的兴趣,为此他拿出了一个长度为n的非负整数序列a1,a2,⋯,an。 zxa觉得这样太单调了,于是他定义了一种方法funct(x,y),表示将ax不可逆转地修改为y后计算⊗1≤i<j≤n(ai+aj)作为该方法的返回值。 zxa很好奇,如果他对这个序列调用m次这样的方法,那么每次得到的返回值分别是多少,你能帮助他吗? 提示:⊗1≤i<j≤n(ai+aj)即(a1+a2)⊗(a1+a3)⊗⋯⊗(a1+an)⊗(a2+a3)⊗(a2+a4)⊗⋯⊗(a2+an)⊗⋯⊗(an−1+an)。
输入描述
第一行有一个正整数T,表示有T组数据。 对于每组数据: 第一行有两个正整数n和m。 第二行有n个非负整数,表示a1,a2,⋯,an。 接下来m行,第i(1≤i≤m)行有两个非负整数x和y,表示第i调用的是funct(x,y)。 每一行相邻数字之间只有一个空格。 1≤T≤1000,2≤n≤2⋅104,1≤m≤2⋅104,0≤ai,y≤109,1≤x≤n,1≤∑n,∑m≤105
输出描述
对于每组数据,输出m行,第i(1≤i≤m)行包含一个非负整数,表示第i次调用方法的返回值。
输入样例
1 3 3 1 2 3 1 4 2 5 3 6
输出样例
4 6 8
Hint
第一次操作后序列为{4,2,3},(4+2)⊗(4+3)⊗(2+3)=4。 第二次操作后序列为{4,5,3},(4+5)⊗(4+3)⊗(5+3)=6。 第三次操作后序列为{4,5,6},(4+5)⊗(4+6)⊗(5+6)=8。
分析:
看题目数据感觉暴力要超时。然而还好数据不是特别严。可以暴力过。但是还是需要优化。
如果每次改了之后重新全部异或铁定是要超时的。但是可以先把所有值异或后值得到。然后只对改了的部分重新异或可得。
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include <cstdio>
#include<cmath>
using namespace std;
int a[100000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
ans^=(a[i]+a[j]);
}
}
for(int i=0;i<m;i++)
{
int r,l;
scanf("%d%d",&r,&l);
for(int k=1;k<=n;k++)
{
if(k!=r)
ans^=(a[k]+a[r]),ans^=(a[k]+l);
}
a[r]=l;
printf("%d\n",ans);
}
}
return 0;
}