题意:
n个点的树, 每个点有权值,
对于每个k= [ 0 , m) , 求有多少个子图满足权值异或和为k.
n<= 1e3 , m<= 1024
解法:
d[ i] [ j] 表示以包含点i且以i为根的子树中, 异或和为j的方案数.
转移:
d[ x] [ ] += d[ x] [ ] 卷d[ v] [ ] 即可.
复杂度O ( n^ 2 * log) .
ps:
c++ 编译失败, g++ 编译成功
code:
# include <bits/stdc++.h>
# define int long long
# define ll long long
# define ull unsigned long long
# define ST ( x) x. begin ( )
# define ED ( x) x. end ( )
# define RST ( x) x. rbegin ( )
# define RED ( x) x. end ( )
# define CL ( x) x. clear ( ) ;
# define all ( a, n) a+ 1 , a+ 1 + n
# define ff ( i, n) for ( ll i= 1 ; i<= n; i++ )
# define rff ( i, n) for ( ll i= n; i>= 1 ; i-- )
# define fff ( i, n) for ( ll i= 0 ; i< n; i++ )
# define rfff ( i, n) for ( ll i= n- 1 ; i>= 0 ; i-- )
# define SC ( x) scanf ( "%s" , x)
# define SL ( x) strlen ( x)
# define pss ( a) push_back ( a)
# define ps ( a) push ( a)
# define SZ ( x) ( int ) x. size ( )
# define pee puts ( "" ) ;
# define eee putchar ( ' ' ) ;
# define re readdd ( )
# define pr ( a) printtt ( a)
int readdd ( ) { int x= 0 , f= 1 ; char c= getchar ( ) ;
while ( ! isdigit ( c) && c!= '-' ) c= getchar ( ) ;
if ( c== '-' ) f= - 1 , c= getchar ( ) ;
while ( isdigit ( c) ) x= x* 10 + c- '0' , c= getchar ( ) ;
return f* x; }
void printtt ( int x) { if ( x< 0 ) putchar ( '-' ) , x= - x;
if ( x>= 10 ) printtt ( x/ 10 ) ; putchar ( x% 10 + '0' ) ; }
int gcd ( int a, int b) { return b== 0 ? a: gcd ( b, a% b) ; }
int ppow ( int a, int b, int mod) { a%= mod;
int ans= 1 % mod; while ( b) { if ( b& 1 ) ans= ( long long ) ans* a% mod;
a= ( long long ) a* a% mod; b>>= 1 ; } return ans; }
bool addd ( int a, int b) { return a> b; }
int lowbit ( int x) { return x& - x; }
const int dx[ 4 ] = { 0 , 0 , 1 , - 1 } ;
const int dy[ 4 ] = { 1 , - 1 , 0 , 0 } ;
bool isdigit ( char c) { return c>= '0' && c<= '9' ; }
bool Isprime ( int x) {
for ( int i= 2 ; i* i<= x; i++ ) if ( x% i== 0 ) return 0 ;
return 1 ;
}
void ac ( int x) { if ( x) puts ( "YES" ) ; else puts ( "NO" ) ; }
# define VE vector< int >
# define PI pair< int , int >
using namespace std;
const int mod= 1e9 + 7 ;
const int maxm= 2e6 + 5 ;
const int inv2= ppow ( 2 , mod- 2 , mod) ;
int d[ 1111 ] [ 2222 ] ;
int temp[ 2222 ] ;
int ans[ 2222 ] ;
int a[ maxm] ;
VE g[ maxm] ;
int n, m;
int len;
void fwt_xor ( int * a, int op) {
for ( int i= 1 ; i< len; i<<= 1 ) {
for ( int j= 0 , p= i<< 1 ; j< len; j+= p) {
for ( int k= 0 ; k< i; k++ ) {
int x= a[ j+ k] , y= a[ i+ j+ k] ;
a[ j+ k] = ( x+ y) % mod;
a[ i+ j+ k] = ( x- y+ mod) % mod;
if ( op== - 1 ) {
a[ j+ k] = 1ll * a[ j+ k] * inv2% mod;
a[ i+ j+ k] = 1ll * a[ i+ j+ k] * inv2% mod;
}
}
}
}
}
void dfs ( int x, int fa) {
for ( int i= 0 ; i< len; i++ ) d[ x] [ i] = 0 ;
d[ x] [ a[ x] ] = 1 ;
for ( int & v: g[ x] ) {
if ( v== fa) continue ;
dfs ( v, x) ;
for ( int i= 0 ; i< len; i++ ) temp[ i] = d[ x] [ i] ;
fwt_xor ( temp, 1 ) ;
fwt_xor ( d[ v] , 1 ) ;
for ( int i= 0 ; i< len; i++ ) {
temp[ i] = 1ll * temp[ i] * d[ v] [ i] % mod;
}
fwt_xor ( temp, - 1 ) ;
fwt_xor ( d[ v] , - 1 ) ;
for ( int i= 0 ; i< len; i++ ) {
d[ x] [ i] = ( d[ x] [ i] + temp[ i] ) % mod;
}
}
}
void solve ( ) {
n= re, m= re;
ff ( i, n) a[ i] = re;
ff ( i, n) CL ( g[ i] ) ;
ff ( i, n- 1 ) {
int x= re, y= re;
g[ x] . pss ( y) ;
g[ y] . pss ( x) ;
}
len= 1 ;
while ( len< m) len<<= 1 ;
dfs ( 1 , 1 ) ;
fff ( j, m) ans[ j] = 0 ;
ff ( i, n) {
fff ( j, m) {
ans[ j] = ( ans[ j] + d[ i] [ j] ) % mod;
}
}
fff ( j, m) {
if ( j) eee;
pr ( ans[ j] ) ;
}
pee;
}
void Main ( ) {
# define MULTI_CASE
# ifdef MULTI_CASE
int T; cin>> T; while ( T-- )
# endif
solve ( ) ;
}
void Init ( ) {
# ifdef SYNC_OFF
ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ;
# endif
# ifndef ONLINE_JUDGE
freopen ( "../in.txt" , "r" , stdin ) ;
freopen ( "../out.txt" , "w" , stdout ) ;
# endif
}
signed main ( ) {
Init ( ) ;
Main ( ) ;
return 0 ;
}