Codeforces 题面传送门 & 洛谷题面传送门

一道个人感觉挺有意思的交互题,本人一开始想了个奇奇怪怪的做法,还以为卡不进去,结果发现竟然过了,而且还是正解(

首先看到这类题目可以考虑每次删掉一个质数的倍数,即对某个 \(pr_i\) 执行 B 操作,然后对 \(pr_i\) 进行 A 询问,根据询问得到的值是否等于理论上删去这些数后 \(pr_i\) 的倍数个数来判断 \(pr_i\) 是否是 \(x\) 的因数,如果是那么就枚举 \(pr_i\) 的 \(2,3,4,\cdots\) 次方,再对这些次方执行 A 询问,以此来判断 \(x\) 质因数分解式中 \(pr_i\) 的次数。

算下询问次数,询问 \(pr_i\) 的 \(2,3,4,\cdots\) 的次数显然与 \(x\) 质因数分解式中 \(x\) 每个质因数的次数之和有关,是 \(\log\) 级别的,最多只有 \(20\) 可以忽略,瓶颈在于每个质因数都要进行两次操作,打表可以发现 \(10^5\) 以内质因数个数刚好比 \(10^4\) 小个几百,因此 \(2\pi(n)\) 是 \(2\times 10^4\) 级别的,过不去。

考虑优化,很明显对于 B 操作而言,我们是可以在操作的同时问出 \(x\) 的倍数的,而刚刚的解法中并没有利用这个性质,因此考虑从这个性质入手解题,我们还是从小到大枚举质因子,只不过与刚才不同的一点是,我们不每进行一次 B 询问都跟一个 A 询问,我们只做 B 询问,那么对于大多数质数,每次 B 询问时也可以根据结果知道该质数是否是 \(x\) 的因子,只有一个例外——那就是 \(x\) 的最小质因子,因此接下来我们只用找到 \(x\) 的最小质因子及它的次数即可,这也是本题的难点所在,我就在这个地方卡了 20+min 后想到了这个解法。

注意到 A 操作起始下标是可以从 \(1\) 开始的,而通过 \(A\ 1\) 我们则可以知道刚才询问的数中是否出现了 \(x\) 的质因子,因此我们考虑根分,每 100 次 B 询问来一次 A 1,那么我们可以把质因子按大小分为 \(\lceil\dfrac{\pi(n)}{100}\rceil\),显然最小质因子就在最后一个 A 1 等于剩余数个数与第一个 A 1 不等于剩余数个数的位置之间,中间部分就暴力枚举质因子然后用 A 质因子判断即可,这样总操作次数为 \(\pi(n)+100+\lceil\dfrac{\pi(n)}{100}\rceil+\log n\),实测询问次数最多 9700+ 次,刚好卡过。

const int MAXN=1e5;
int n,pr[MAXN/5+5],prcnt=0;
bool vis[MAXN+5],is[MAXN+5],has[MAXN+5];
vector<int> fac[MAXN+5];
int cnt[MAXN+5];
void sieve(){
for(int i=2;i<=n;i++){
if(!vis[i]) pr[++prcnt]=i;
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;
if(i%pr[j]==0) break;
}
}
for(int i=1;i<=n;i++) cnt[i]=n/i;
for(int i=1;i<=prcnt;i++) for(ll j=pr[i];j<=n;j*=pr[i]) is[j]=1;
for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i) fac[j].pb(i);
}
void del(int x){for(int y:fac[x]) cnt[y]--;has[x]=1;}
void del_mul(int x){for(int i=x;i<=n;i+=x) if(!has[i]) del(i);}
int qr1(int x){printf("A %d\n",x);fflush(stdout);int res;scanf("%d",&res);return res;}
int qr2(int x){printf("B %d\n",x);fflush(stdout);int res;scanf("%d",&res);return res;}
int main(){
scanf("%d",&n);sieve();
int cur=1,mn=prcnt,cc=0,fst_blk=0;
for(int i=1;i<=prcnt;i++){
int t=qr2(pr[i]);
if(t!=cnt[pr[i]]){
if(cur==1) mn=i;del_mul(pr[i]);
cur*=pr[i];
for(ll x=1ll*pr[i]*pr[i];x<=n;x*=pr[i]){
int num=qr1(x);//printf("%d %d\n",x,cnt[x]);
if(num==cnt[x]) break;cur*=pr[i];
}
} else del_mul(pr[i]);
++cc;
if(cc==100&&!fst_blk){
cc=0;int x=qr1(1);
if(x!=cnt[1]) fst_blk=i;
}
} if(!fst_blk){int x=qr1(1);if(x!=cnt[1]) fst_blk=prcnt;}
for(int j=(fst_blk-1)/100*100+1;j<=min(fst_blk,mn);j++){
int x=qr1(pr[j]);
if(x!=cnt[pr[j]]){
cur*=pr[j];
for(ll k=1ll*pr[j]*pr[j];k<=n;k*=pr[j]){
int num=qr1(k);//printf("%d %d\n",x,cnt[x]);
if(num==cnt[k]) break;cur*=pr[j];
} break;
}
}
printf("C %d\n",cur);fflush(stdout);
return 0;
}

Codeforces 1406E - Deleting Numbers(根分+数论)的更多相关文章

  1. Codeforces - 55D Beautiful numbers (数位dp+数论)

    题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...

  2. Codeforces 1446D2 - Frequency Problem (Hard Version)(根分)

    Codeforces 题面传送门 & 洛谷题面传送门 人菜结论题做不动/kk 首先考虑此题一个非常关键的结论:我们设整个数列的众数为 \(G\),那么在最优子段中,\(G\) 一定是该子段的众 ...

  3. CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

    传送门 参考资料: [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化) 我的理解: 起初,我先定义一个三维数组 dp[ i ][ j ][ ...

  4. Codeforces 878 E. Numbers on the blackboard

    Codeforces 878 E. Numbers on the blackboard 解题思路 有一种最优策略是每次选择最后面一个大于等于 \(0\) 的元素进行合并,这样做完以后相当于给这个元素乘 ...

  5. PAT 甲级 1069 The Black Hole of Numbers (20 分)(内含别人string处理的精简代码)

    1069 The Black Hole of Numbers (20 分)   For any 4-digit integer except the ones with all the digits ...

  6. PAT 甲级 1023 Have Fun with Numbers (20 分)(permutation是全排列题目没读懂)

    1023 Have Fun with Numbers (20 分)   Notice that the number 123456789 is a 9-digit number consisting ...

  7. Codeforces 55D. Beautiful numbers(数位DP,离散化)

    Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...

  8. 1069 The Black Hole of Numbers (20分)

    1069 The Black Hole of Numbers (20分) 1. 题目 2. 思路 把输入的数字作为字符串,调用排序算法,求最大最小 3. 注意点 输入的数字的范围是(0, 104), ...

  9. 1023 Have Fun with Numbers (20 分)

    1023 Have Fun with Numbers (20 分)   Notice that the number 123456789 is a 9-digit number consisting ...

随机推荐

  1. Golang通脉之数组

    数组是同一种数据类型元素的集合.数组在内存中都是连续存放的. 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化. 基本语法: // 定义一个长度为3元素类型为int的数组 ...

  2. cassandra表中主键的类型

    cassandra表中主键的类型及区分? 一.类型及区分 二.参考文章 一.类型及区分 Cassandra的4种Key Primary Key 主键 Composite Key,Compound Ke ...

  3. 【二食堂】Beta - Scrum Meeting 6

    Scrum Meeting 6 例会时间:5.19 18:30~18:50 进度情况 组员 当前进度 今日任务 李健 1. 实体标注的优化基本已经实现,后端有bug,还没有进行接口调用 issue 2 ...

  4. RocketMQ源码详解 | Producer篇 · 其二:消息组成、发送链路

    概述 在上一节 RocketMQ源码详解 | Producer篇 · 其一:Start,然后 Send 一条消息 中,我们了解了 Producer 在发送消息的流程.这次我们再来具体下看消息的构成与其 ...

  5. Noip模拟54 2021.9.16

    T1 选择 现在发现好多题目都是隐含的状压,不明面给到数据范围里,之凭借一句话 比如这道题就是按照题目里边给的儿子数量不超过$10$做状压,非常邪门 由于数据范围比较小,怎么暴力就怎么来 从叶子节点向 ...

  6. 2021.9.26考试总结[NOIP模拟62]

    T1 set 从\(0\)到\(n\)前缀余数有\(n+1\)个,但只有\(n\)种取值,找到一样的两个输出区间即可. \(code:\) T1 #include<bits/stdc++.h&g ...

  7. Linux C 数据结构 ->单向链表

    之前看到一篇单向链表的博文,代码也看着很舒服,于是乎记录下来,留给自己~,循序渐进,慢慢 延伸到真正的内核链表~(敢问路在何方?路在脚下~) 1. 简介 链表是Linux 内核中最简单,最普通的数据结 ...

  8. 计算机网络之IPv4(IPv4分组、IPv4地址、NAT、子网划分与子网掩码、CIDR、ARP协议、DHCP、ICMP)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105138313 学习课程:<2019王道考研计算机网络> 学习目的 ...

  9. xmake v2.5.9 发布,改进 C++20 模块,并支持 Nim, Keil MDK 和 Unity Build

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  10. Python报错ModuleNotFoundError: No module named 'numpy'

    转载:https://blog.csdn.net/qq_39779233/article/details/103224712 Python报错ModuleNotFoundError: No modul ...