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. WPF中的命令(Command)

    这节来讲一下WPF中的命令(Command)的使用. [认识Command] 我们之前说过,WPF本身就为我们提供了一个基础的MVVM框架,本节要讲的命令就是其中一环,通过在ViewModel中声明命 ...

  2. Kafka消息(存储)格式及索引组织方式

    要深入学习Kafka,理解Kafka的存储机制是非常重要的.本文介绍Kafka存储消息的格式以及数据文件和索引组织方式,以便更好的理解Kafka是如何工作的. Kafka消息存储格式 Kafka为了保 ...

  3. LeetCode:动态规划

    动态规划 动态规划永远的神 这部分主要是学习了 labuladong 公众号中对于动态规划的讲解 刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 题目 这部分内容直接上题目了,解题 ...

  4. mybatis学习笔记(1)基本环境

    1.pom引入 <dependencies> <dependency> <groupId>org.mybatis</groupId> <artif ...

  5. Go 语言实现 gRPC 的发布订阅模式,REST 接口和超时控制

    原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...

  6. BUAA2020软工作业——提问回顾与个人总结

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾与个人总结 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方 ...

  7. Intellij IDEA 2021.2.3 最新版免费激活教程(可激活至 2099 年,亲测有效)

    ​ 申明,本教程 Intellij IDEA 最新版破解.激活码均收集与网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除.如条件允许,建议大家购买正版. 本教程更新于:2021 年 10 月 ...

  8. 轻松掌握stm32直流电机驱动与测速

    说实话就现在的市场应用中stm32已经占到了绝对住到的地位,51已经成为过去式,32的功能更加强大,虽然相应的难度有所增加,但是依然阻止不了大家学习32的脚步,不说大话了这些大家都懂要不然也不会学习s ...

  9. 用STM32内置的高速ADC实现简易示波器

    做一个数字采样示波器一直是我长久以来的愿望,不过毕竟这个目标难度比较大,涉及的方面实在太多,模拟前端电路.高速ADC.单片机.CPLD/FPGA.通讯.上位机程序.数据处理等等,不是一下子就能成的,慢 ...

  10. C语言编程基础有网盘资料哦

    刚开始看STM32的库函数,会有很多疑惑,例如指针怎么用,结构体跟指针怎么配合,例如函数的参数有什么要求,如何实时更新IO口的数据等.如果重新进行C语言的学习,那么要学很久才能够系统地认识.本文则将比 ...