CodeForces 763C. Timofey and remoduling
来源:互联网 发布:海康威视网络摄像头 编辑:程序博客网 时间:2024/06/06 02:51
题解:智商题,不考算法,考脑洞
先考虑2*n<=m的情况
考虑a中的两个元素之差,假设它们在最后序列的位置为i,i+k,那么它们之差为k*d%m
由于保证2*n<=m所以这样的差只会出现n-k次,nlogn统计这个差出现的次数,于是我们就求出了k,从而求出了d,然后check即可
如果2*n>m
之前提到的差不会只出现n-k次,因为可能经过多遍,
那么把m内a的补集做一次,然后首项加上公差*项数即可(保证m是质数)
据说这题m不是质数也能做,有没有神犇教我一下啊QAQ
#include <bits/stdc++.h> using namespace std; const int MAXN = 100010; int ans = -1, ansd, a[MAXN], b[MAXN], n, m; inline int Pow(int x, int y, int mod) { int s = 1; for( ; y ; y >>= 1, x = 1ll * x * x % mod ) if( y & 1 ) s = 1ll * s * x % mod; return s; } inline bool find(int *a, int n, int x) { int t = lower_bound( a + 1, a + n + 1, x ) - a; return a[ t ] == x; } inline void solve(int *a, int n) { if( n == 1 ) { ans = a[ 1 ], ansd = 1; return ; } int tmp = a[ 2 ] - a[ 1 ], cnt = 0; for( int i = 1 ; i <= n ; i++ ) if( find( a, n, ( a[ i ] + tmp ) % m ) ) cnt++; ansd = 1ll * tmp * Pow( n - cnt , m - 2, m ) % m; int d = ( m - ansd ) % m; for( int i = 1 ; i <= n ; i++ ) if( !find( a, n, ( a[ i ] + d ) % m ) ) { if( ans == -1 ) ans = a[ i ]; else { ans = -1; return ; } } } int main() { scanf( "%d%d", &m, &n ); for( int i = 1 ; i <= n ; i++ ) scanf( "%d", &a[ i ] ); sort( a + 1, a + n + 1 ); if( n == 1 || n == m ) return printf( "%d 1\n", a[ 1 ], 1 ), 0; if( 2 * n < m ) solve( a, n ); else { int t = 0; for( int i = 0 ; i < m ; i++ ) if( !find( a, n, i ) ) b[ ++t ] = i; solve( b, t ); if( ans != -1 ) ( ans += 1ll * ansd * t % m ) %= m; } if( ans == -1 ) return printf( "-1\n" ), 0; return printf( "%d %d\n", ans, ansd ), 0; }
上面是q神的解法,下面还有一种解法:
解题思路:
首先需要知道两个公式:
1.等差数列各项和公式变形:a1=(Sn-n*(n-1)/2*d)/n
2.等差数列各项的平方的和的公式:Sn^2=n(a1)^2+n(n-1)(2n-1)d^2/6+n(n-1)*d*a1(以前不知道这公式。。)
先讲a序列从小到达排列,我们去枚举a[i]-a[0],因为a[i]中肯定有与a[0]相邻的点,所以我们一定能求出一个d,这个我已开始对一个特殊情况有疑问,问了q神后才知道,如果求不出d来,那么可以求出一个-d然后再加上就m就是合法的。
我想的特殊情况是a序列是2,4,6,8,对m为7取模后为1,2,4,6,这样的就求不出2这个公差了,但是问了q神之后知道,这样求出公差-2,对7取模后最小的数是8,因为和8相邻的点只有6了,那么就求出一个reverse过的公差-2(即6-8)的序列,在这里-2+m就是5,也就是6-1得到的数据。orz,模q
我们枚举出q后,可以根据公式1求出首项a1,这里由于除数有未知量,所以取模要求逆元,用费马小定理求一下就可以,然后再用公式2去验证是否满足来判断,d和a1是否正确。在这基础上还要确定下求出来的序列是否和a序列相同,相同就是符合的解了。
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+5; int a[maxn]; int b[maxn]; int fp(int a, int n,int m) { int res=1; int tem=a; while(n) { if(n&1)res=1LL*res*tem%m; tem=1LL*tem*tem%m; n>>=1; } return res; } int main() { int n, m; cin>>m>>n; int i; int s[2]; s[0]=s[1]=0; for(i=0; i<n; i++) { scanf("%d", &a[i]); s[0]=(a[i]+s[0])%m; s[1]=(s[1]+1LL*a[i]*a[i]%m)%m; } if(n==1)return 0*printf("%d 0\n", a[0]); if(n==m)return 0*printf("0 1"); sort(a, a+n); for(int i=1; i<n; i++) { int d=(a[i]-a[0]); int x=(s[0]-1LL*n*(n-1)/2%m*d%m+m)*fp(n,m-2,m)%m; int tem=1LL*n*x%m*x%m; tem=(tem+1LL*n*(n-1)%m*d%m*x%m)%m; tem=(tem+1LL*n*(n-1)*(2*n-1)/6%m*d%m*d%m)%m; if(s[1]==tem) { b[0]=x; for(int i=1; i<n; i++) { b[i]=(b[i-1]+d)%m; } sort(b, b+n); // for(int i=0; i<n; i++)printf("%d ", b[i]); // printf("\n"); bool isok=true; for(int i=0; i<n; i++)isok&=(a[i]==b[i]); if(isok)return 0*printf("%d %d\n", x, d); } } printf("-1\n"); return 0; }
- CodeForces 763C. Timofey and remoduling
- CodeForces 763C. Timofey and remoduling
- codeforces 763 C Timofey and remoduling(数学)
- E. Timofey and remoduling----数论及数学公式
- 764E Timofey and remoduling[数学]
- Codeforces Round #395 (Div. 2)E: Timofey and remoduling(数学+数论)
- 【codeforces 764C】Timofey and a tree
- CodeForces 764C Timofey and a tree
- Codeforces 763A-Timofey and a tree
- Codeforces 763B-Timofey and rectangles
- CodeForces 763A Timofey and a tree
- C. Timofey and a tree codeforces 395 div2 C
- Codeforces 764C或763A Timofey and a tree 【好题】
- Codeforces 764C - Timofey and a tree(dfs)
- Codeforces 764C Timofey and a tree 树+思维
- Codeforces Round #395 (Div. 2) C. Timofey and a tree
- 【codeforces 764C】Timofey and a tree 题解
- Codeforces 764C Timofey and a tree(思路)
- 运算符重载-编程题#3(C++程序设计第4周)
- JS实现HTML5音频播放自定义UI
- Linux线程模型比较
- bzoj 3105 线性基
- Nginx支持Socket转发过程详解
- CodeForces 763C. Timofey and remoduling
- 1008. 数组元素循环右移问题 (20)
- 不重复数
- Poj 3658 Artificial Lake(模拟)
- 核心DOM和html DOM的区别
- 1009. 说反话 (20)
- PAT-1122. Hamiltonian Cycle (25)
- 创建快捷方式——解决部分机型创建不了或图标文案不正确
- 使用docker而无须加sudo