Just do it
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 546 Accepted Submission(s): 302
Problem Description
There is a nonnegative integer sequence
a1...n
of length
n
. HazelFan wants to do a type of transformation called prefix-XOR, which means
a1...n
changes into
b1...n
, where
bi
equals to the XOR value of
a1,...,ai
. He will repeat it for
m
times, please tell him the final sequence.
Input
The first line contains a positive integer
T(1≤T≤5)
, denoting the number of test cases.
For each test case:
The first line contains two positive integers n,m(1≤n≤2×105,1≤m≤109) .
The second line contains n nonnegative integers a1...n(0≤ai≤230−1) .
For each test case:
The first line contains two positive integers n,m(1≤n≤2×105,1≤m≤109) .
The second line contains n nonnegative integers a1...n(0≤ai≤230−1) .
Output
For each test case:
A single line contains n nonnegative integers, denoting the final sequence.
A single line contains n nonnegative integers, denoting the final sequence.
Sample Input
2 1 1 1 3 3 1 2 3
Sample Output
1 1 3 1
Source
——————————————————————————————————
题目的意思是给出一种变化,第一个数不变,后面每个数与前缀XOR,求变化m次后的序列
思路:比赛的时候先直接找了循环节,然后虽然存在但是炸了;后来发现每个数字在变幻出现的位置有规律,如下图:黄色表示会出现的位置,白色表示不会
是不是规律很明显,它是高度对称的,所以我们对于一些要求的方格,可以把他等价到前2*2格。容易计算出01.
所以我们只要算出第m行(取模后),然后对于第二个数我们只需把这一行向右平移一格,依次类推答案就出来了
然后小数据这样写 比如m等于1的时候效率很慢,黄格太多了,效率可能会n*n/2,所以小数据暴力大数据处理
(赛后发现不存在m=1的情况和mod处理后=1的情况,所以小数据特殊处理去了也过了)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <algorithm>
#include <complex>
#include <vector>
#include <bitset>
#include <stack>
#include <queue>
#include <unordered_map>
#include <functional>
using namespace std;
int a[200009],m,n;
int ans[200009],x[200009];
bool f(int x,int y)
{
while(1)
{
if(x==1||y==1)
return 1;
int ma=max(x,y);
int s=log2(ma-1);
int ss=pow(2,s);
if(x>ss&&y>ss)
return 0;
if(x>ss) x-=ss;
if(y>ss) y-=ss;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
memset(ans,0,sizeof ans);
int k = 1,flag=0;
while(k < n) k*=2;
m%=k;
if(!m)m = k;
if(m < 1000)
{
for(int i = 0; i < m; i++)
{
for(int j = 2; j <= n; j++)
{
a[j] ^= a[j - 1];
}
}
for(int i=1; i<=n; i++)
{
if(flag) printf(" ");
else flag=1;
printf("%d",a[i]);
}
printf("\n");
continue;
}
for(int i=1; i<=n; i++)
{
if(f(m,i))
{
for(int j=i; j<=n; j++)
{
ans[j]^=(a[1+j-i]);
}
}
}
for(int i=1; i<=n; i++)
{
if(flag) printf(" ");
else flag=1;
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}