hdu5909Tree Cutting

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5909

题意:给定一棵无根树,统计所有子树的异或和的个数。

分析:求出所有子树的异或和,题解的两种方法我都写了一下。第一种是FWT加速卷积O(n*m*logn)。第二种是树分治,因为是无根树,我们可以每次用树dp确定过重心的方案数,然后每次删掉重心就是树分治啦O(n*mlgon)。

fwt代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const db eps=1e-5;
const int N=1e3+30;
const int M=1e5+10;
const ll MOD=1000000007;
const int mod=1000000007;
const int MAX=1000000010;
const double pi=acos(-1.0);
int n,m,w[N],tot,u[N],v[2*N],pre[2*N];
ll d[N],ans[N],dp[N][N];
void add(int a,int b) {
    v[tot]=b;pre[tot]=u[a];u[a]=tot++;
    v[tot]=a;pre[tot]=u[b];u[b]=tot++;
}
void fwt(ll a[],int n,ll inv) {
    int i,j,k,h;
    for (h=1;h

树分治代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const db eps=1e-5;
const int N=1e3+30;
const int M=1e5+10;
const ll MOD=1000000007;
const int mod=1000000007;
const int MAX=1000000010;
const double pi=acos(-1.0);
int n,m,w[N],tot,u[N],v[2*N],pre[2*N];
ll ans[N],dp[N][N];
void add(int a,int b) {
    v[tot]=b;pre[tot]=u[a];u[a]=tot++;
    v[tot]=a;pre[tot]=u[b];u[b]=tot++;
}
int sum,root,f[N],vis[N],siz[N];
void get_root(int a,int b) {
    f[a]=0;siz[a]=1;
    for (int i=u[a];~i;i=pre[i])
    if (v[i]!=b&&!vis[v[i]]) {
        get_root(v[i],a);
        siz[a]+=siz[v[i]];
        f[a]=max(f[a],siz[v[i]]);
    }
    f[a]=max(f[a],sum-siz[a]);
    if (f[a]


你可能感兴趣的:(online,judge,Hdu,动态规划,树形dp,数据结构,树分治,数学,FFT)