B. Restore Modulo
原题链接
题面
For the first place at the competition, Alex won many arrays of integers and was assured that these arrays are very expensive. After the award ceremony Alex decided to sell them. There is a rule in arrays pawnshop: you can sell array only if it can be compressed to a generator.
This generator takes four non-negative numbers n, m, c, s. n and m must be positive, s non-negative and for c it must be true that 0≤c<m. The array a of length n is created according to the following rules:
a1=smodm, here xmody denotes remainder of the division of x by y;
ai=(ai−1+c)modm for all i such that 1<i≤n.
For example, if n=5, m=7, c=4, and s=10, then a=[3,0,4,1,5].
Price of such an array is the value of m in this generator.
Alex has a question: how much money he can get for each of the arrays. Please, help him to understand for every array whether there exist four numbers n, m, c, s that generate this array. If yes, then maximize m.
input
The first line contains a single integer t (1≤t≤105) — the number of arrays.
The first line of array description contains a single integer n (1≤n≤105) — the size of this array.
The second line of array description contains n integers a1,a2,…,an (0≤ai≤109 ) — elements of the array.
It is guaranteed that the sum of array sizes does not exceed 105.
Output
For every array print:
−1, if there are no such four numbers that generate this array;
0, if m can be arbitrary large;
the maximum value m and any appropriate c (0≤c<m) in other cases.
Example
Input
6
6
1 9 17 6 14 3
3
4 2 2
3
7 3 4
3
2 2 4
5
0 1000000000 0 1000000000 0
2
1 1
Output
19 8
-1
-1
-1
2000000000 1000000000
0
题意
给出四个数n,m,c,s。按照:
a1=s%m
ai=(ai−1+c)%m (c<m)
以上两个条件一次表示a[i]从0直到n
题目要求给出已经表示出的数组的值,让我们逆推出是否存在这么4个数,如果存在输入最大的m和适当的c,如果无限大输出0,不存在输出-1
思路
从题意c<m中我们容易得出,如果a[i]>=a[i-1],则a[i]-a[i-1]是一定等于c。
如果a[i] <= a[i-1],那么我们可以得出a[i-1] + c = m + a[i]所以m = a[i-1] - a[i] + c,由此我们可以设b = a[i-1] - a[i]
于是我们只要能够确定唯一的b和c就能确定m了。
(我靠这么简单的问题当时怎么就不会呢)呜呜
代码如下
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL a[N];
int main(void)
{
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=0;i<n;i++)cin >> a[i];
int flag = 1;
LL b = -1,c = -1;
for(int i=1;i<n;i++)
{
if(a[i]-a[i-1]>=0){
if(c==-1)c = a[i] - a[i-1];
else{
if(c!=a[i]-a[i-1]){
flag = 0;
break;
}
}
}else if(a[i] - a[i-1] <=0){
if(b==-1)b = a[i-1] - a[i];
else {
if(b!=a[i-1]-a[i]){
flag = 0;
break;
}
}
}
}
if(flag==1){
LL num = b+c;
if(c==-1||b==-1||(c==0&&b==0))cout << "0" << endl;
else {
sort(a,a+n);
if(num<=a[n-1])cout << "-1" << endl;
else cout << b+c << " " << c << endl;
}
}else cout << "-1" << endl;
}
return 0;
}