传送门:【HDU】4421 Bit Magic
题目分析:将一个数拆成31位,分别用2-sat判断是否符合即可。
代码如下:
#include <map> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std ; typedef long long LL ; #pragma comment ( linker , "/STACK:1024000000" ) #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define rec( i , A , o ) for ( int i = A[o] ; i != o ; i = A[i] ) #define clr( a , x ) memset ( a , x , sizeof a ) const int MAXN = 505 ; const int MAXE = 1000005 ; struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {} } ; Edge E[MAXE] ; int H[MAXN << 1] , cntE ; int scc[MAXN << 1] , scc_cnt ; int dfn[MAXN << 1] , low[MAXN << 1] , dfs_clock ; int S[MAXN << 1] , top ; int b[MAXN][MAXN] ; int n ; void clear () { top = 0 ; cntE = 0 ; scc_cnt = 0 ; dfs_clock = 0 ; clr ( H , -1 ) ; clr ( scc , 0 ) ; clr ( dfn , 0 ) ; } void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ; } void tarjan ( int u ) { dfn[u] = low[u] = ++ dfs_clock ; S[top ++] = u ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( !dfn[v] ) { tarjan ( v ) ; low[u] = min ( low[u] , low[v] ) ; } else if ( !scc[v] ) low[u] = min ( low[u] , dfn[v] ) ; } if ( low[u] == dfn[u] ) { ++ scc_cnt ; do { scc[S[-- top]] = scc_cnt ; } while ( u != S[top] ) ; } } bool check () { rep ( i , 0 , n ) if ( scc[i << 1] == scc[i << 1 | 1] ) return 0 ; return 1 ; } void scanf ( int& x , char c = 0 ) { while ( ( c = getchar () ) < '0' || c > '9' ) ; x = c - '0' ; while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ; } void solve () { rep ( i , 0 , n ) rep ( j , 0 , n ) scanf ( b[i][j] ) ; rep ( i , 0 , 31 ) { clear () ; rep ( j , 0 , n ) { rep ( k , 0 , n ) { if ( j == k ) continue ; if ( j % 2 == 1 && k % 2 == 1 ) { if ( ( b[j][k] >> i ) & 1 ) { addedge ( j << 1 | 1 , k << 1 ) ; addedge ( k << 1 | 1 , j << 1 ) ; } else { addedge ( j << 1 | 1 , k << 1 | 1 ) ; addedge ( k << 1 | 1 , j << 1 | 1 ) ; } } else if ( j % 2 == 0 && k % 2 == 0 ) { if ( ( b[j][k] >> i ) & 1 ) { addedge ( j << 1 , k << 1 ) ; addedge ( k << 1 , j << 1 ) ; } else { addedge ( j << 1 , k << 1 | 1 ) ; addedge ( k << 1 , j << 1 | 1 ) ; } } else { if ( ( b[j][k] >> i ) & 1 ) { addedge ( j << 1 , k << 1 | 1 ) ; addedge ( k << 1 , j << 1 | 1 ) ; addedge ( j << 1 | 1 , k << 1 ) ; addedge ( k << 1 | 1 , j << 1 ) ; } else { addedge ( j << 1 , k << 1 ) ; addedge ( k << 1 , j << 1 ) ; addedge ( j << 1 | 1 , k << 1 | 1 ) ; addedge ( k << 1 | 1 , j << 1 | 1 ) ; } } } } rep ( u , 0 , n ) if ( !dfn[u] ) tarjan ( u ) ; if ( !check () ) { printf ( "NO\n" ) ; return ; } } printf ( "YES\n" ) ; } int main () { while ( ~scanf ( "%d" , &n ) ) solve () ; return 0 ; }