题目大意
这是一道交互题。
现在有若干只地鼠,你只知道地鼠数量
≤
M
\leq M
≤M,你要把这个数量猜出来。
你有 18 个风扇。每天初始,你给每个风扇设定它的叶片数
b
i
b_i
bi(2 到 18 之间,从 0 开始标号),然后都让 0 号叶片指向正下。接着,每只地鼠独立地、等概率地选择一个风扇,把它的叶片往前拨一位(即原来是
j
j
j 号叶片向下的现在变成
(
j
+
1
)
m
o
d
b
i
(j+1)~mod~b_i
(j+1) mod bi 号叶片向下)。
你告诉电脑
b
b
b 序列,它告诉你这天结束时各风扇指向正下的叶片编号。
你要在至多
N
N
N 天之内猜出来。
T
a
s
k
1
:
N
=
365
,
M
=
100
Task1: N=365,~M=100
Task1:N=365, M=100
T
a
s
k
2
:
N
=
7
,
M
=
1
0
6
Task2: N=7,~M=10^6
Task2:N=7, M=106
题解
Task1:
没想出来。。。
Task2:
看到 N = 7 N=7 N=7,马上想到 18 18 18 以内恰好只有 7 7 7 个质数,用这 7 7 7 个质数做模数,然后解中国剩余定理!!
——Zayin
他从看完题到想出这一串东西总共用了 10s
对于每一天,所有的风扇叶片数都取同一个模数
p
p
p,那么这一天你把最终状态加起来,就知道了地鼠数量
m
o
d
  
p
\mod p
modp 的值。
7 天就把
2
、
3
、
5
、
7
、
11
、
13
、
17
2、3、5、7、11、13、17
2、3、5、7、11、13、17 全部试一遍,这就有了 7 个同余方程。然后跑 CRT 就行了。
根据 CRT,这个方程组在
2
∗
3
∗
5
∗
.
.
.
∗
17
=
510510
2*3*5*...*17=510510
2∗3∗5∗...∗17=510510 内有唯一解。
好像不够大?那把 2 2 2 换成 16 16 16、 3 3 3 换成 9 9 9 就可以啦!
代码
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long LL;
const int maxs=50005, maxlen=55;
int n,m,p[7]={5,7,11,13,17,16,9};
LL ny(LL x,int pi)
{
fo(i,1,p[pi]-1) if (x*i%p[pi]==1) return i;
}
int T;
int main()
{
LL P=1;
fo(i,0,6) P*=p[i];
scanf("%d%d%d",&T,&n,&m);
fo(ti,1,T)
{
LL ans=0;
fo(i,0,6)
{
LL a=0;
fo(j,1,18) printf("%d ",p[i]);
puts("");
fflush(stdout);
fo(j,1,18)
{
int x;
scanf("%d",&x);
(a+=x)%=p[i];
}
(ans+=a*(P/p[i])%P*ny(P/p[i],i))%=P;
}
printf("%lld\n",ans);
fflush(stdout);
int res;
scanf("%d",&res);
}
}