https://codeforces.com/contest/1562/submission/202004961
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=1e5+10;
const int M=90;
int n,a[N],b[M][M],prime[N];
int rnd(){
return (rand()*rand())%n+1;
}
int gcd(int x,int y){
if(!x)
return y;
return __gcd(x,y);
}
int ask(int x,int y){
if(n<=85){
if(x>y)
swap(x,y);
if(b[x][y]!=0)
return b[x][y];
cout<<"? "<<x<<' '<<y<<endl;
b[x][y]=read();
return b[x][y];
}
cout<<"? "<<x<<' '<<y<<endl;
int p=read();
return p;
}
void print(){
cout<<"! ";
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
cout<<endl;
for(int i=1;i<=n;i++)
a[i]=0;
memset(b,0,sizeof(b));
}
int get(int x){
int res=0;
for(int i=1;i<=n;i++){
if(i==x)
continue;
int p=ask(i,x);
if(!res)
res=p;
else res=__gcd(res,p);
}
return res;
}
signed main()
{
for(int i=2;i<N;i++){
if(prime[i])
continue;
for(int j=i+i;j<N;j+=i)
prime[j]=1;
}
int T=read();
while(T--){
n=read();
if(n<=85){
if(n==3){
for(int i=1;i<=n;i++)
a[i]=get(i);
if(abs(a[1]-a[2])==2)
a[3]=(a[1]+a[2])/2;
else if(abs(a[1]-a[3])==2)
a[2]=(a[1]+a[3])/2;
else if(abs(a[2]-a[3])==2)
a[1]=(a[2]+a[3])/2;
print();
continue;
}
for(int i=1;i<=n;i++)
a[i]=get(i);
print();
continue;
}
int t=250,res=0,pos=0;
while(t--){
int x=rnd(),p=0;
for(int i=1;i<=20;i++){
int y=rnd();
if(x==y)
continue;
p=gcd(p,ask(x,y));
}
if(prime[p])
continue;
if(p>res){
res=p;
pos=x;
}
}
a[pos]=res;
for(int i=1;i<=n;i++){
if(i==pos)
continue;
a[i]=ask(i,pos)/res;
}
print();
}
return 0;
}
感谢。