[CTS2024] 多方计算
C1942huangjiaxu · · 题解
题目中要求不能使用全局变量,但因为 CTS 是 IOI 赛制,这里认为在调用 transmit 函数时可以知道
先考虑逐位确定答案,具体如下 :
- 第一轮,
0 号将a_0 的第0 位信息传给1 号。 - 第二轮,
1 号将0 号的信息加上,可以确定a_0+a_1 的第0 位信息,1 号将这个信息传给2 号,同时这一轮0 号将第1 位信息传给1 号。 - 第
j 轮,i 号将j-i-1 位的信息传给第i+1 号。
最后答案的位数是
参考代码
#include "mpc.h"
int precalc(int n,int m){
int t=0;
while((1<<t)<n)++t;
return n+m+t;
}
bool transmit(player &player, int round,int position){
int np=round-position-1;
if(np<0)return 0;
int o=player.last_message;
if(o){
int l=np;
while(player.memory[l])player.memory[l]=0,++l;
player.memory[l]=1;
}
return player.memory[np];
}
考虑到上述做法中,在第
考虑我们同步进行两轮加法,后面一轮不必要从第 0 位开始,但要在第
参考代码
#include "mpc.h"
int N,M;
int precalc(int n,int m){
N=n,M=m;
return n+m+4;
}
bool transmit(player &player, int round,int position){
int np=round-position-1,o=player.last_message,lp;
if(np<0)np=np+M+11;
if(np<0)return 0;
if(o){
lp=np;
while(player.memory[lp])player.memory[lp]=0,++lp;
player.memory[lp]=1;
}
bool u=player.memory[np];
if(position!=N)player.memory[np]=0;
return u;
}
既然两次不够,考虑同时进行三轮加法,把最后面的三角形往后移,中间再从
参考代码
#include "mpc.h"
const int B=8,C=4;
int N,M;
int precalc(int n,int m){
N=n,M=m;
return n+m+3;
}
bool transmit(player &player, int round,int position){
int np=round-position-1,o=player.last_message,lp;
if(np<0){
if(np>=-B)np=np+M+C;
else np=np+M+B+11;
}
if(np<0)return 0;
if(o){
lp=np;
while(player.memory[lp])player.memory[lp]=0,++lp;
player.memory[lp]=1;
}
bool u=player.memory[np];
if(position!=N)player.memory[np]=0;
return u;
}