Codeforces 1114E(数学+随机算法)
Posted birchtree
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1114E(数学+随机算法)相关的知识,希望对你有一定的参考价值。
题面
分析
通过二分答案,我们显然可以求出数组中最大的数,即等差数列的末项
接着随机取一些数组中的数,对他们两两做差,把得到的差取gcd即为公差
例a={1,5,9,13},我们随机取了1 9 13,两两的差为8,4,12,取gcd为4
已知末项和公差即可求出首项
可以证明错误的概率< (1.86185 imes10?^{-9})
具体证明我也不懂,可以看cf官方题解,需要用到莫比乌斯反演
注意生成随机数时不能直接用rand(),因为rand()的返回值<32768,而n很可能>32768,需要用rand()*rand()再%n
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int n;
int ask1(int x){
printf("? %d
",x);
fflush(stdout);
int ans=0;
scanf("%d",&ans);
return ans;
}
int ask2(int x){
printf("> %d
",x);
fflush(stdout);
int ans=0;
scanf("%d",&ans);
return ans;
}
int asks=0;
int bin_search(int l,int r){
int ans=0;
while(l<=r){
int mid=(l+r)>>1;
asks++;
if(ask2(mid)){
l=mid+1;
}else{
ans=mid;
r=mid-1;
}
}
return ans;
}
int a[62];
inline int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
inline int random(){
return (long long)rand()*rand()%n+1;
}
int main(){
srand(19260817);
scanf("%d",&n);
fflush(stdout);
int x=bin_search(0,1e9+1);
// printf("debug:%d
",x);
for(int i=1;i<=60-asks;i++){
a[i]=ask1(random());
}
int ans=0;
for(int i=1;i<=60-asks;i++){
for(int j=i+1;j<=60-asks;j++){
ans=gcd(ans,abs(a[i]-a[j]));
}
}
printf("! %d %d
",x-ans*(n-1),ans);
}
以上是关于Codeforces 1114E(数学+随机算法)的主要内容,如果未能解决你的问题,请参考以下文章
codeforces#1305F. Kuroni and the Punishment(随机算法)
[Codeforces 1295F]Good Contest(DP+组合数学)
解题报告(十八)Codeforces - 数学题目泛做(难度:2000 ~ 3000 + )
Codeforces 1106F Lunar New Year and a Recursive Sequence (数学线性代数线性递推数论BSGS扩展欧几里得算法)