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

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
  
  
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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值