Codeforces Round 919 (Div. 2). Partitioning the Array同余的同余

Problem - C - Codeforces

目录

题目要求:

一些样例解释:

0.总思路:

1.同余定理:

2.所以看 a-b :

3.对于每个对应位置,都只和第一个作差比较就够了:(传递性)

4.直接对m求gcd。

m的倍数可以,m也可以(我的公约数的公约数也是我的公约数)

5.核心代码


题目要求:

这道题是给个数组,划分为几个子数组,看是否有个数m,对每个数取余后,使得这些子数组完全相同。

每有一个m,ans+1。

(时间复杂度的计算可以看大佬博客Codeforces Round 919 (Div. 2) (A-D)-CSDN博客

一些样例解释:

//第一个样例k = 1是不可以的

//1 3 1 1 3 1
//k = 6
//k = 3
//k = 2  m = 2
//k = 1  m = 2

//6 2 6 2 2 2
//k = 6
//k = 3  m = 4 
//k = 2  m = 4
//k = 1  m = 4

0.总思路:

我们就是要找m嘛,直接找不好找,所以接下来的步骤就是转换m,使其有更紧密简单的关系,进而容易求解。

1,2是说出其中的关联。

3则是省去多余的比较。

4更是利用性质,把整个过程给联系起来了

1.同余定理:

两个数模完相同,那么他们的差值是这个除数的倍数

 a%m == b%m    ∴|a-b|%m == 0

(直接找不好找,我们可以转换。这也将前后联系起来了。)


2.所以看 a-b :

直观的例子:

比如 a c b d 我们分为 a c 和 b d 两组,那么要的就是 a%m == b%m,c%m == d%m。

即(a-b)%m==0,(c-d)%m==0。

即m是a-b和c-d的公约数     ——>每组应数的差值是m的倍数  ——>公约数

m不可以是1

所以

若存在m使得两个区间%m后是相同的,那么这些对应数的差(的绝对值)的最大公约数不能是1,而得是m



3.对于每个对应位置,都只和第一个作差比较就够了:(传递性)

证明:

(a-b)%m == (a-c)%m == 0
说明b和c差若干个m ,即(b-c)%m == 0

(不然要遍历太多次)


4.直接对m求gcd。

m的倍数可以,m也可以(我的公约数的公约数也是我的公约数)

(原理:  7对4取余和对2取余的结果是相同的)

我们可以求出每个位置的m,几个m之间还得再进行一次gcd。

因为我的公约数的公约数也是我的公约数,而符合的约数也只会小于等于m啦,所以我们直接对m进行gcd即可

(两数相等差值为0也处理掉了,a == a,两数相等不管对谁取余都是相等的,不需要处理)

5.核心代码

for (int k = 1; k <= n-1; k++)
{
	if (n % k == 0)//可等分
	{
        int tmp = 0;
        for (int i = 0; i < k; i++)//每组
        {
    	    for (int j = i; j + k < n; j += k)
    	    {
    	    	tmp = gcd(tmp, abs(arr[j+k]-arr[j]));
    	    }
        }
        if (tmp != 1)ans++;
    }
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值