题解:P17766 「LDOI R2」位运算 / Bit
题解:P17766 「LDOI R2」位运算 / Bit
思路
由于位运算的每一位是互相独立的,因此我们不妨从高位到低位枚举
我们先判断这一位是否有解,再考虑如何分配才能让乘积最大。
如果
如果
我们发现只有
为了让乘积尽量大,我们当然希望取
注意到或运算为
只有那些
于是我们先假设所有数都等于
我们要最大化的是
还没有被删过任何位的数,其
对于每个关键位,它的权值是
在
举个例子,假设
所以把减量加给当前
由于我们是从高位到低位处理,权值
对于
对于
所有位处理完之后,堆中的每个
如果中途任何一位判定无解,直接输出
代码
::::success[代码]
#include <bits/stdc++.h>
#define endl '\n'
#define MOD 998244853
#define int unsigned long long
using namespace std;
int sz, cnt, tot;
int bits[65], ms[65], hp[205];
void push(int v)
{
hp[++sz] = v;
int i = sz;
while (i > 1 && hp[i] < hp[i / 2])
{
swap(hp[i], hp[i / 2]);
i /= 2;
}
}
void pop()
{
hp[1] = hp[sz--];
int i = 1;
while (1)
{
int l = i * 2, r = l + 1, mid = i;
if (l <= sz && hp[l] < hp[mid])
mid = l;
if (r <= sz && hp[r] < hp[mid])
mid = r;
if (mid == i)
break;
swap(hp[i], hp[mid]);
i = mid;
}
}
int qpow(int a, int b)
{
long long c = a % MOD, res = 1;
while (b)
{
if (b & 1)
res = res * c % MOD;
c = c * c % MOD;
b >>= 1;
}
return res;
}
char buf[1 << 20], *p1, *p2;
char gc()
{
if (p1 == p2)
p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin);
return *p1++;
}
int rd()
{
int s = 0;
char c = gc();
while (c < 48)
c = gc();
while (c > 47)
s = s * 10 + (c ^ 48), c = gc();
return s;
}
int T, n, k, x, y, z, f, ans;
void mian()
{
n = rd(), x = rd(), y = rd(), z = rd(), f = 1;
cnt = tot = sz = 0, k = n, ans = 1;
for (signed b = 59; b >= 0; b--)
{
int xb = (x >> b) & 1, yb = (y >> b) & 1, zb = (z >> b) & 1;
if (xb)
{
if (!yb || zb != (n & 1))
{
f = 0;
break;
}
}
else if (yb)
{
if (n == 1)
{
f = 0;
break;
}
int t = (n & 1) ^ zb, m;
if (n == 2)
{
if (t != 1)
{
f = 0;
break;
}
m = 1;
}
else
m = 1 + (t == 0);
bits[++cnt] = b;
ms[cnt] = m;
tot += m;
}
else if (zb)
{
f = 0;
break;
}
}
if (!f)
return cout << -1 << endl, void();
for (int i = 1; i <= cnt; i++)
{
int w = 1ULL << bits[i];
int m = ms[i];
if (m == 1)
{
if (k > 0)
{
k--;
push(w);
}
else
{
int h = hp[1];
pop();
push(h + w);
}
}
else
{
if (k >= 2)
{
k -= 2;
push(w);
push(w);
}
else if (k == 1)
{
k = 0;
int h = hp[1];
pop();
push(w);
push(h + w);
}
else
{
int h1 = hp[1];
pop();
int h2 = hp[1];
pop();
push(h1 + w);
push(h2 + w);
}
}
}
for (int i = 1; i <= sz; i++)
ans = ans * ((y - hp[i]) % MOD) % MOD;
ans = ans * qpow(y % MOD, k) % MOD;
cout << ans << endl;
}
signed main()
{
T = rd();
while (T--)
mian();
return 0;
}
::::