题解:P17766 「LDOI R2」位运算 / Bit
首先有一些明显的特判,就是根据
思考哪些位置我们不确定,发现是二进制下
根据
然后是分配这些缺口,有一个贪心就是尽量均衡的分配,感性思考就是经典的
如果
由于缺口不会很多,后者可以直接暴力。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244853;
int n,x,y,z;
int s[1000005];
int lst[1005];
inline int ksm(int a,int x){
a%=mod;
int res=1;
while (x){
if (x&1){
res=res*a%mod;
}
a=a*a%mod;
x>>=1;
}
return res;
}
vector<pair<int,int> > vec;
inline void solve(){
cin>>n>>x>>y>>z;
if ((x&y)!=x){
cout<<"-1\n";
return;
}
if ((n&1) && ((x&z)!=x)){
cout<<"-1\n";
return;
}
if (!(n&1) && (x&z)){
cout<<"-1\n";
return;
}
if ((~y)&z){
cout<<"-1\n";
return;
}
int w=(~x)&y;
if (!w){
cout<<ksm(x,n)<<'\n';
return;
}
if (n==1){
cout<<"-1\n";
return;
}
vec.clear();
for (int i=0;i<60;i++){
if (w>>i&1ll){
int ww=(z>>i)&1ll;
int op=(n&1)^ww;
int t;
if (op==1){
t=1;
}
else{
t=2;
}
if (t>=n){
cout<<"-1\n";
return;
}
for (int j=0;j<t;j++){
vec.push_back(make_pair((1ll<<i),i));
}
}
}
int len=vec.size();
sort(vec.begin(),vec.end());
reverse(vec.begin(),vec.end());
if (n>=len){
int ans=ksm(y,n-len);
for (int i=0;i<len;i++){
int ww=vec[i].first;
ans=(y%mod-ww%mod+mod)%mod*ans%mod;
}
cout<<ans<<'\n';
}
else{
for (int i=0;i<=n;i++){
s[i]=0;
}
for (int i=0;i<=70;i++){
lst[i]=-1;
}
for (int i=0;i<len;i++){
int ww=vec[i].first;
int id=vec[i].second;
int pos=-1;
for (int j=0;j<n;j++){
if (j==lst[id]){
continue;
}
if (pos==-1 || s[j]<s[pos]){
pos=j;
}
}
lst[id]=pos;
s[pos]+=ww;
}
int ans=1;
for (int i=0;i<n;i++){
ans=(y%mod-s[i]%mod+mod)%mod*ans%mod;
}
cout<<ans<<'\n';
}
return;
}
int T;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>T;
while (T--){
solve();
}
return 0;
}