Hdu6129 Just do it(2017多校第7场)

来源:互联网 发布:网络彩票停售 编辑:程序博客网 时间:2024/06/07 22:37

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(1T5), denoting the number of test cases.
For each test case:
The first line contains two positive integers n,m(1n2×105,1m109).
The second line contains n nonnegative integers a1...n(0ai2301).
 

Output
For each test case:
A single line contains n nonnegative integers, denoting the final sequence.
 

Sample Input
21 113 31 2 3
 

Sample Output
11 3 1
 

Source
2017 Multi-University Training Contest - Team 7

——————————————————————————————————
题目的意思是给出一种变化,第一个数不变,后面每个数与前缀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;}