题解:P17115 [Algo Beat 009 & MROI-R1] ANDOR
题解:P17115 [Algo Beat 009 & MROI-R1] ANDOR
传送门
思路
首先
::::success[证明]{open}
设
枚举四种组合:
-
x=0,y=0$:$(x\operatorname{and} y)+(x\operatorname{or} y)=0+0=x+y -
x=0,y=1$:$(x\operatorname{and} y)+(x\operatorname{or} y)=0+1=x+y -
x=1,y=0$:$(x\operatorname{and} y)+(x\operatorname{or} y)=0+1=x+y -
x=1,y=1$:$(x\operatorname{and} y)+(x\operatorname{or} y)=1+1=x+y
把要求证的式子展开:
左边:
由上面的结论
将整数
其中
右边:
左边等于右边,所以对任意非负整数
::::
于是我们可以先求出
又因为
总询问次数为
代码
int main()
{
int n = rd(), k = rd();
int a, b;
cout << "? and 1 2" << endl;
a = rd();
cout << "? or 1 2" << endl;
b = rd();
ll s12 = a + b;
cout << "? and 1 3" << endl;
a = rd();
cout << "? or 1 3" << endl;
b = rd();
ll s13 = a + b;
cout << "? and 2 3" << endl;
a = rd();
cout << "? or 2 3" << endl;
b = rd();
ll s23 = a + b;
p[1] = (s12 + s13 - s23) / 2;
p[2] = s12 - p[1];
p[3] = s13 - p[1];
ll sum = p[1] + p[2] + p[3];
for (int i = 4; i <= n - 1; i++)
{
cout << "? and 1 " << i << endl;
a = rd();
cout << "? or 1 " << i << endl;
b = rd();
p[i] = a + b - p[1];
sum += p[i];
}
p[n] = (ll)n * (n - 1) / 2 - sum;
cout << "! ";
for (int i = 1; i <= n; i++)
cout << p[i] << ' ';
cout << endl;
return 0;
}