CF1114E Arithmetic Progression(交互题,二分,随机算法)
既然是在CF上AC的第一道交互题,而且正是这场比赛让我升紫了,所以十分值得纪念。
题目链接:CF原网
题目大意:交互题。
有一个长度为 $n$ 的序列 $a$,保证它从小到大排序后是个等差数列。你不知道这个序列长什么样,但你可以询问:
- $?\ i$ 表示询问 $a_i$ 的值;
- $>\ x$ 表示询问序列中是否存在严格大于 $x$ 的数。
你可以问不超过 $60$ 个询问。
现在,你需要求出这个等差数列的首项(也就是 $a$ 中的最小值)和这个等差数列的公差(也就是等差数列中相邻两个数的差)。
$2\le n\le 10^6,0\le a_i\le 10^9$。
看,第二个操作,明显暗示我们要二分最大值。(除了这个也没啥用了吧?)
用掉 $\log 10^9=30$ 个操作。
令 $mx$ 为我们二分出的最大值。
设公差为 $d$,那么 $\forall 1\le i\le n,d|(mx-a_i)$。
也就是如果我们知道的 $a_i$ 有 $x_1,x_2,x_3\dots,x_k$,那么 $d|\gcd(mx-x_1,mx-x_2,mx-x_3\dots,mx-x_k)$。
但这样就有一个严峻的问题:如果 $k$ 不够大,直接 $\gcd$ 得到的可能不是答案!
无路可走了,只有一个想法:随机!
我们随机 $30$ 个 $i$,询问这些 $a_i$ 的值。(为什么要随机呢?因为如果直接取前 $30$ 个 $a_i$ 很可能会被毒瘤卡掉)
$d$ 就是所有 $mx-a_i$ 的 $\gcd$ 了。
???这样不会错吗?
分析一下,我们设 $a_1=mx-k_1d,a_2=mx-k_2d\dots a_n=mx-k_nd$。那么我们求出的 $\gcd$ 就是随机出的 $30$ 个 $k_i$ 的 $\gcd$。
在 $10^6$ 中随机选 $30$ 个数,$\gcd$ 不为 $1$ 的概率就是出错的概率。
大致估算一下:
选出的 $k$ 都是 $2$ 的倍数的概率是 $\frac{1}{2^{30}}$。
选出的 $k$ 都是 $3$ 的倍数的概率是 $\frac{1}{3^{30}}$。
等等等等……
这样估算的话,出错概率是不会超过 $10^{-8}$ 的。
其实有更准确的求法,就是莫比乌斯反演,但由于我们只是来证明正确性的,就不讲了。
直接引用官方题解:
By some maths, we can find out the probability of our solution to fail being relatively small — approximately $1.86185\times 10^{-9}$.
直接上rand()就做完了……
了吗?
对了,这就是出题人恶毒所在了……
rand()和random_shuffle()的上界都是32767,访问不到后面大部分的元素。
于是出题人就把恶毒的数放在了前面……
那就用自己的rand()啊!写过treap吗?把那个rand搬过来就能用了!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
char ch=getchar();int x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,cnt,pt[maxn];
inline int rnd(){ //自己的rand
static int seed=;
return seed=(((seed*666666ll+)%)^)%;
}
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
int main(){
n=read();
if(n<=){ //n<=60,随便玩
int mx=,mn=INT_MAX;
FOR(i,,n){
printf("? %d\n",i);
fflush(stdout);
int x=read();
mx=max(mx,x);
mn=min(mn,x);
}
printf("! %d %d\n",mn,(mx-mn)/(n-));
fflush(stdout);
return ;
}
int l=,r=1e9;
while(l<r){ //二分最大值
int mid=(l+r)>>;
printf("> %d\n",mid);
cnt++;
fflush(stdout);
int ver=read();
if(ver) l=mid+;
else r=mid;
}
int mx=r,ans=;
FOR(i,,n) pt[i]=i;
FOR(i,,n) swap(pt[i],pt[rnd()%n+]);
FOR(i,,min(n,-cnt)){ //随机60-cnt个元素
printf("? %d\n",pt[i]);
fflush(stdout);
int x=read();
ans=gcd(ans,mx-x); //取gcd
}
printf("! %d %d\n",mx-(n-)*ans,ans); //首项=末项-(项数-1)*公差
fflush(stdout);
}
CF1114E Arithmetic Progression(交互题,二分,随机算法)的更多相关文章
- Codeforces Round #371 (Div. 2) D. Searching Rectangles 交互题 二分
D. Searching Rectangles 题目连接: http://codeforces.com/contest/714/problem/D Description Filya just lea ...
- CF1370F2-The Hidden Pair(Hard Version)【交互题,二分】
正题 题目链接:https://www.luogu.com.cn/problem/CF1370F2 题目大意 \(T\)组数据,给出\(n\)个点的一棵树,有两个隐藏的关键点.你每次可以询问一个点集, ...
- CF1114E Arithmetic Progression
给定一个打乱的等差数列,每次两种操作. 1.查询一个位置. 2.查询是否有比x大的数字. 一共60次操作. sol: 30次操作即可二分出首项. 剩下30次操作查询出30个位置然后两两做差取gcd即可 ...
- Codeforces 1114E - Arithmetic Progression - [二分+随机数]
题目链接:http://codeforces.com/problemset/problem/1114/E 题意: 交互题,有一个 $n$ 个整数的打乱顺序后的等差数列 $a[1 \sim n]$,保证 ...
- Subway Pursuit (二分)(交互题)
题目来源:codeforces1039B Subway Pursuit 题目大意: 在1到n里有一个运动的点,要求找到这个点,每次可以查询一个区间内有没有这个点,每次这个点往左或者往右移动1到k个位置 ...
- Codeforces Round #499 (Div. 2) D. Rocket_交互题_二分
第一次作交互题,有点不习惯. 由于序列是循环的,我们可以将一半的机会用于判断当前是否是在说谎,另一半的机会用于二分的判断. 对于判断是否实在说谎,用1判断即可.因为不可能有比1还小的数. 本题虽然非常 ...
- 【Warrior刷题笔记】力扣169. 多数元素 【排序 || 哈希 || 随机算法 || 摩尔投票法】详细注释 不断优化 极致压榨
题目 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/majority-element/ 注意,该题在LC中被标注为easy,所以我们更多应该关 ...
- CF 1114 E. Arithmetic Progression
E. Arithmetic Progression 链接 题意: 交互题. 有一个等差序列,现已打乱顺序,最多询问60次来确定首项和公差.每次可以询问是否有严格大于x的数,和查看一个位置的数. 分析: ...
- 随机算法 - HNU 13348 Finding Lines
Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&am ...
随机推荐
- 【php增删改查实例】第十六节 - 用户新增
6.1工具栏 <div id="toolbar"> <a href="javascript:openDialog()" class=" ...
- 破解Zip加密文件常用的几种方法
前言 在互联网的浪潮中,大家也许碰到过这种情况: 从网络上下载了一个zip文件,最后却发现它是用密码保护的,或者自己用密码加密了一个很重要zip文件,但是一段时间后忘记了密码,无法打开.这个时候,我们 ...
- python-编码-15
ascii A : 00000010 8位 一个字节 unicode A : 00000000 00000001 00000010 00000100 32位 四个字节 中:00000000 00000 ...
- B. Math
链接 [http://codeforces.com/contest/1062/problem/B] 题意 给你n,有两种操作要么乘以某个数,要么开根但必须开根后是整数才能开,问你最后能变成最小的数是多 ...
- 对spring cloud config的一点理解
以下部分纯属个人理解,但是结果都是经过demo验证. 一.spring cloud config介绍 spring cloud是spring家族中的一个微服务工具包,其中包含了很多微服务的工具.偏向于 ...
- Linux内核分析——Linux内核学习总结
马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核学习总结 一 ...
- 语音笔记:CTC
CTC全称,Connectionist temporal classification,可以理解为基于神经网络的时序类分类.语音识别中声学模型的训练属于监督学习,需要知道每一帧对应的label才能进行 ...
- mybatis中批量更新的问题
问题:使用mybatis在执批量更新操作时,一直报错执行失败 解决方法: 首先打印了SQL语句,发现SQL语句拿出来执行没问题,也可以批量执行.SQL没问题,应该是配置的问题. 在网上查询和很多资料, ...
- [福大软工] Z班 第11次成绩排行榜
注:本次成绩排行榜是针对团队Alpha阶段冲刺博客的得分统计 作业要求 http://www.cnblogs.com/easteast/p/7749181.html 评分细则 在团队Alpha阶段刚开 ...
- org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: c
//这个是 配置文件放错了地方 org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing ...