Codeforces 1484B. Restore Modulo(思维+构造)

18 篇文章 0 订阅

题目链接

题意:

给出你n个数a[i],让你构造出b[]满足:

  • a[i]=b[i].
  • b[1]=s%m.
  • b[i]=(b[i-1]+c)%m;

让你求最大的m,和适当的c.

题解:

很明显我们需要去构造,而且需要判断我们构造出来的是否跟a数组相等,

我们先看一个性质,因为我们每次都是+c那么如果 b [ i + 1 ] > b [ i ] b[i+1]>b[i] b[i+1]>b[i] 那我们是不是可以先把 ( b [ i + 1 ] − b [ i ] ) (b[i+1]-b[i]) (b[i+1]b[i])当作我们c.那么既然是固定的c,那么如果还有 b [ j + 1 ] > b [ j ] b[j+1]>b[j] b[j+1]>b[j] 那么就会有另一差值,如果相等那么c就是固定的,如果不等,就可以说明没有答案.

而如果 b [ i + 1 ] < b [ i ] b[i+1]<b[i] b[i+1]<b[i]所说明 b [ i ] + c > m b[i]+c>m b[i]+c>m那么这个差值也是固定的.

剩下的就是利用这两个差值,来找到我们要得最大m.(两个数的和)

在这里插入图片描述
软件不好用就这样把,
c是我们求出来的增量就是c,-值是我们的负差, x是a[i],y是a[i]+c,d是y%m的结果,我们知道,a+b=c,我们要求m从图中可以知道,等于负值加上c.这就是最大的m,
之后我们只需要挨个判断每个a[i]是否符合题意即可.


void solve()
{
    scanf("%lld", &n);
    d = -1, p = -1;
    for(int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
    }

    for(int i = 1; i < n; i++)
    {
        ll ch = a[i + 1] - a[i];
        if(ch > 0)
        {
            if(d == -1)
            {
                d = ch;
            }
            else
            {
                if(d != ch)
                {
                    puts("-1");
                    return ;
                }
            }
        }
        else
        {
        	ch=-ch;
            if(p == -1)
            {
                p = ch;
            }
            else
            {
                if(p != ch)
                {
                    puts("-1");
                    return ;
                }
            }

        }
    }

    if(p == -1 || d == -1)
    {
        puts("0");
        return ;
    }
    ll sum = p + d;

    if(a[1] >= sum) ///取余m就说明没有大于等于m的
    {
        printf("-1\n");
        return ;
    }
    b[1]=a[1];
    for(int i = 2; i <= n; ++i)
    {
        b[i] = (b[i - 1] + d) % sum;
        if(b[i] != a[i])
        {
            puts("-1");
            return ;
        }
    }
    printf("%lld %lld\n", sum, d);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值