题目传送门
分析:
两发询问出结果,又要感受人类智慧了
先第一次询问\(2^{15}\),得到答案x,我们知道\(P|2^{30}-x\)
如果\(x=0\),那么\(P=2\),偶质数唯一确定可以结束
否则\(P\)为奇质数,我们知道\(\frac{2^{30}-x+1}{2}\equiv \frac{1}{2}(mod~P)\)
第二次询问\(\frac{2^{30}-x+1}{2}\)得到\(y\),那么\(y\equiv \frac{1}{4}(mod~P)\)
所以\(y\)是模\(P\)意义下4的逆元
\(P\)为奇质数,分类讨论一下:
若\(P\equiv 1(mod~4)\),则\(y=\frac{3P+1}{4},P=\frac{4y-1}{3}\)
若\(P\equiv 3(mod~4)\),则\(y=\frac{P+1}{4},P=4y-1\)
\(\frac{4y-1}{3}\)和\(4y-1\)不可能同时为质数(因为多一个因子3),特判一下出答案
果然人类智慧
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<string>
#define maxn 1000005
#define INF 0x3f3f3f3f
using namespace std;
inline int getint()
{
int num=0,flag=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
return num*flag;
}
char s[maxn];
inline int ask(int x)
{printf("1 %d\n",x),fflush(stdout);return getint();}
inline void answer(int x)
{printf("2 %d\n",x),fflush(stdout),scanf("%s",s);return;}
int main()
{
int T=getint();
while(T--)
{
int x=ask(1<<15);
if(!x){answer(2);continue;}
x=(1<<30)-x;
while(!(x&1))x>>=1;
x=ask((x+1)/2);
if(x==1||(4ll*x-1)%3)answer(4ll*x-1);
else answer((4ll*x-1)/3);
}
}