[JZOJ5449] Pacifist
来源:互联网 发布:趣头条刷阅读量软件 编辑:程序博客网 时间:2024/06/05 03:30
题目描述
papyrus 喜欢谜题… 来解一道如何?
在你面前有一个被加密了的数组,其原数组是一个等差序列,你面前的则是将原数组中的所有数字都对m 取模再打乱后而得到的新数组
papyrus 给你出的谜题就是还原出原等差序列
因为papyrus 喜欢质数,所以他给你出的谜题中的m 一定是质数
对于10% 的数据满足2<= m <= 5
对于另10% 的数据满足n = m
对于另10% 的数据满足n = m - 1
对于100% 的数据满足2 <= m <= 10^9 +7; 2 <= n <= 10^5,m 是质数,给出的序列中有可能有相同元素。
分析
这道题方法就很多了,思维比较发散。
先讲不太稳的算法。随便选定一个数a_i,它跟另外每一个数的差,一定有一个是公差。那么我们可以枚举公差,然后再来判断是否合法。
随机超时水法的判断方式是:二分确定首项是什么,即二分看看减多少个公差回到首项。因为如果公差合法,那么ai往前连续一段肯定都出现在数组中,而且m是质数,不会有鬼畜情况。唯一的鬼畜情况是2n>=m,二分的上界太大,有可能跳到序列的末尾,这时候要调整二分上界,这里可能花费很多时间。这之后,我们随机判断等差数列每一项是否出现,实现我用的是把所有系数random shuffle一下。这样我们期望复杂度大概是
另一个类似哈希的特征值判断方法是利用等差数列的一、二、三次求和的公式进行判断。我们枚举公差,然后用
一个比较靠谱的方法是利用等差数列的性质。我们随便找一个数,再枚举序列的每一个数,我们知道
代码
给出第一个水法代码…
#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<set>using namespace std;typedef long long ll;typedef double db;#define fo(i,j,k) for(i=j;i<=k;i++)#define fd(i,j,k) for(i=j;i>=k;i--)#define cmax(a,b) (a=(a>b)?a:b)#define cmin(a,b) (a=(a<b)?a:b)const int N=1e5+5,mo=60000011;int D,l,r,mid,tmp,a[N],b[N],v[mo+5],i,j,n,m,pp,k,st,kan;int hash(int x){ k=x%mo; while (v[k]&&v[k]!=x+1) k=(k+1)%mo; return k;}int main(){ freopen("t1.in","r",stdin);// freopen("t1.out","w",stdout); scanf("%d %d",&m,&n); if (m==n) { printf("0 1\n"); return 0; } fo(i,1,n) scanf("%d",a+i); if (n==1) { printf("%d 0\n",a[1]); return 0; } fo(i,1,n-1) b[i]=i; srand(m); random_shuffle(b+1,b+n); sort(a+1,a+1+n); fo(i,1,n) v[hash(a[i])]=a[i]+1; fo(i,2,n) { D=a[i]-a[1]; if (D<0) D+=m; if (D>m/2) D=m-D; if (!D) continue; l=0; st=a[1]; while (l<n-1&&v[hash((st-D+m)%m)]) { r=min(n-1,m-n+l); while (l<r) { mid=(l+r+1)/2; tmp=((a[1]-1ll*mid*D)%m+m)%m; if (v[hash(tmp)]) l=mid; else r=mid-1; } st=((a[1]-1ll*l*D)%m+m)%m; } //st=((a[1]-1ll*l*D)%m+m)%m; pp=1; fo(j,1,n-1) { kan++; tmp=(st+1ll*b[j]*D)%m; if (!v[hash(tmp)]) { pp=0; break; } } if (pp) { printf("%d %d\n",st,D); return 0; } } printf("-1\n");}
- [JZOJ5449] Pacifist
- Codeforces Round #395 Div.1 C pacifist【JZOJ5449】Pacifist
- Jzoj5449【NOIP2017提高A组冲刺11.4】Pacifist
- 【NOIP2017提高A组冲刺11.4】Pacifist
- 【JZOJ 5449】【NOIP2017提高A组冲刺11.4】Pacifist
- [2017纪中11-4][Codeforces Round #395 Div.1]C pacifist
- Attendez-moi 指针数组与strcmp fgets等函数的配合使用
- leetcode编程记录11 #508 Most Frequent Subtree Sum
- 金融类自定义View(一)--仿蚂蚁财富基金收益曲线图
- Binary Tree Maximum Path Sum II
- 【Java基础知识】抽象类与接口
- [JZOJ5449] Pacifist
- Java ConcurrentModificationException异常原因和解决方法
- 算法
- 《隐秩序》第一章:基本元素——摘录与评述
- 数据结构中的线性表代码实现
- 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠2*n的大矩形,总共有多少种方法?
- 算法竞赛入门经典第3章
- 麦克风阵列声音定位简介
- PS之油画制作