Request from \ ((0,0,0) \) come \ ((n, m, r ) \) the number of programs. \ (n-, m, R & lt \ Leq 18 is 10 ^ {} \) . Each \ (S \) may be moved to a point \ (T \) , \ (T \) is the binary representation of the coordinates as \ (1 \) bits must contain all \ (S \) the coordinates binary representation is \ (1 \) bits. Meanwhile, \ (o \ leq 10 ^ 4 \) a checkpoint can not pass. (Original title title description surface toxic)
Solution
Consider first the program number is obtained when there is no obstacle, and apparently only on each coordinate \ (1 \) number related set \ (f [i] [j ] [k] \) represents the three coordinates \ (1 \) number followed by \ (i, j, k \ ) is the number of programs, the number of combinations pretreatment violent transfer \ (C_i ^ l \ cdot f [il] [j] [k] \ to f [i] [J] [K] \) , similar to the other two dimensions
All points in ascending order for each dimension ( \ (X \) is the first keyword, \ (Y \) is the second ......), provided \ (g [i] \) represents come impairment point \ (I \) the number of programs, consider what \ (J \) can be used as a transfer point, clearly there must be \ (x_j \ subseteq x_i, y_j \ subseteq y_i, z_j \ subseteq z_i \) , then the \ (g [i] = f [ x_i] [y_i] [z_i] - \ sum g [j] \ cdot f [i \ xor \ j] \)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 20005;
const int M = 64;
const int mod = 998244353;
namespace popcnter {
int bt[65536];
int popcnt (int x) {
int t=0;
while(x>=65536){
t+=bt[x&65535];
x>>=16;
}
return t+bt[x];
}
void init() {
for(int i=0;i<65536;i++) {
bt[i]=0;
int x=i;
while(x) bt[i]+=(x&1),x>>=1;
}
}
}
using namespace popcnter;
struct point {
int x,y,z;
bool operator < (const point &b) {
if(x-b.x) return x<b.x;
if(y-b.y) return y<b.y;
return z<b.z;
}
} a[N];
int p,q,r,n,f[M][M][M],g[N],c[M][M];
int cor(int x) {
return (x%mod+mod)%mod;
}
signed main() {
ios::sync_with_stdio(false);
init();
cin>>p>>q>>r;
cin>>n;
for(int i=1;i<=n;i++) {
cin>>a[i].x>>a[i].y>>a[i].z;
}
++n;
a[n].x=p; a[n].y=q; a[n].z=r;
sort(a+1,a+n+1);
f[0][0][0]=1;
for(int i=0;i<M;i++) {
c[i][0]=1;
for(int j=1;j<=i;j++) {
c[i][j]=cor(c[i-1][j-1]+c[i-1][j]);
}
}
for(int i=0;i<M;i++) {
for(int j=0;j<M;j++) {
for(int k=0;k<M;k++) {
if(i+j+k) {
for(int l=1;l<=i;l++) f[i][j][k]=cor(f[i][j][k]+f[i-l][j][k]*c[i][l]);
for(int l=1;l<=j;l++) f[i][j][k]=cor(f[i][j][k]+f[i][j-l][k]*c[j][l]);
for(int l=1;l<=k;l++) f[i][j][k]=cor(f[i][j][k]+f[i][j][k-l]*c[k][l]);
}
}
}
}
for(int i=1;i<=n;i++) {
g[i]=f[popcnt(a[i].x)][popcnt(a[i].y)][popcnt(a[i].z)];
for(int j=1;j<i;j++) {
if((a[i].x&a[j].x)==a[j].x && (a[i].y&a[j].y)==a[j].y && (a[i].z&a[j].z)==a[j].z) {
g[i]=cor(g[i]-g[j]*f[popcnt(a[i].x^a[j].x)]
[popcnt(a[i].y^a[j].y)][popcnt(a[i].z^a[j].z)]);
}
}
}
cout<<g[n];
}