HDU 6129 暴力,规律

本文通过分析杨辉三角的特性,找到了一系列变换中数组元素经多次异或操作后的规律,并利用组合数学中的概念来简化计算过程。通过判断组合数的奇偶性,有效地解决了问题。

2017多校7 -1010

找规律

列出前几项,斜着看,是杨辉三角 --> 组合数

异或满足性质:
\(a \oplus b \oplus b = a\)

所以只需要关注组合数的奇偶性就可以了

规律是

  • 对于\(a_1\)来说,那么\(m\)次变换在\(a_n\)上的异或次数为\(C_{m+n-2}^{m-1}\)
  • 对于\(a_2\)来说,那么\(m\)次变换在\(a_n\)上的异或次数为\(C_{m+(n-1)-2}^{m-1}\)

然后发现,对于\(a_2\)来说,就是\(a_1\)整体移了一位,所以如果判断出\(C_{m+i-2}^{m-1}\),这是\(a_1\)在m次变换于\(a_i\)处异或次数,同样上面的组合数也是\(a_2\)在m次变换在\(a_{i+1}\)处的异或次数,所以可以将其都计算上去

判断奇偶性可以数组合数分子分母2的个数
****
代码

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <string>
#include <math.h>
#include <ctype.h>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int N = 2e5 + 5;
int t,a[N],ans[N];

LL getx(int n, int x)
{
    LL ans = 0;
    while(n)
    {
        ans += n/x;
        n /= x;
    }
    return ans;
}

int judge(int n, int m)
{
    LL x = getx(n, 2);
    LL y = getx(m, 2) + getx(n-m, 2);
    return x == y;
}
int n,m;
int main()
{
    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));
        for(int i = 1; i <= n; i++)
        {
            int f = judge(i+m-2, m-1);
            if(f)
            {
                int p = 1;
                for(int j = i; j <= n; j++)
                    ans[j] ^= a[p++];
            }
        }

        for(int i = 1; i <= n; i++)
        {
            if(i != 1) printf(" ");
            printf("%d", ans[i]);
        }
        printf("\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/Alruddy/p/7368554.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值