题目来源
题意
给一个数组arr(最大为2e5),给出一种操作,求出arr的每个前缀异或和,作为新的arr.
操作最大次数为1e9,问最后的arr数组是啥
想法
1.M这么大,本能就想找规律(赛上还找错了…)
2.赛下重新打了一次表,发现了1 - 2 - 4 - 8的规律(打表到8就知道了)
3.规律有了1e9进行二进制枚举就行(这里和快速幂很像)
写的时候注意细节,容易越界(代码如下)
AC代码
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <math.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#define sc(x) scanf("%d",&x);
#define pr(x) cout << x << endl;
#define bug(x) cout << #x << " = " << x << endl;
#define ppr(x,y) cout << "(" << x << "," << y << ")" << endl;
#define mem(arr,x) memset(arr,x,sizeof arr);
#define clr(arr) mem(arr,0);
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int a[maxn];
int n,m;
void F(int x){ //m = x 时的变换
for(int i = x + 1; i <= n ; ++i)
a[i] ^= a[i - x];
}
void _Bit(){ //用二进制枚举把m 分解成二进制乘积的变换
int x = 1;
while(m){
if(m & 1){
F(x);
}
x *= 2;
m >>= 1;
}
}
int main(){
ios::sync_with_stdio(false);
int T;
sc(T)
while(T--){
scanf("%d%d",&n,&m);
for(int i = 1 ; i <= n ; i++) scanf("%d",a + i);
_Bit();
for(int i = 1; i <= n ; i++) printf("%d%c",a[i],i == n ? '\n' : ' ');
}
}