多彩的樹 點分治 抽屜定理

2021-10-05 18:58:08 字數 2247 閱讀 8098

其中

很明顯的乙個二進位制維護,因為k真的很小,我們可以利用二進位制來做。

但是,我們不能

但是,點分治維護的資訊要是「或」的和的資訊,因為二進位制的數量是少的,而點的數量是多的,譬如說第一次點分的時候,點的數量是e4級別的,而二進位制資訊是最多e3級別的,可以根據抽屜定理(鴿巢定理),我們用e3級別的少的來降低複雜度。

所以,最後比賽的時候,我的**是最快的(超得意。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 5e4 + 7;

const ll mod = 1e9 + 7;

ll bas[12], ans = 0, f[12];

inline int calc(int x) return sum; }

int n, head[maxn], cnt, k, a[maxn];

struct eddge

} edge[maxn << 1];

inline void addeddge(int u, int v)

inline void _add(int u, int v)

int root, maxx, all;

bool vis[maxn] = ;

int siz[maxn], son[maxn];

void findroot(int u, int fa)

son[u] = max(son[u], all - siz[u]);

if(son[u] < maxx)

}vectorvt, nt;

int sum[1 << 10] = , dp[maxn] = , stap[maxn], stop, cdq_sum[1 << 10] = , dp_sum[1 << 10] = ;

void dfs(int u, int fa)

}void divide(int u)

len2 = (int)nt.size();

for(int j=0; j= mod) sum[vt[k] | nt[j]] %= mod;}}

for(int j=0; j= mod) cdq_sum[nt[j]] %= mod;

dp_sum[nt[j]] = 0;

}nt.clear();

}len = (int)vt.size();

for(int i=0; isiz[u] ? totsiz - siz[u] : siz[v];

maxx = inf;

findroot(v, 0);

divide(root);

}}inline void init()

int main()

for(int i=1, u, v; i

maxx = inf; all = n;

findroot(1, 0);

divide(root);

int _up = (1 << k) - 1;

for(int i=1, num; i<=_up; i++)

for(int i=1; i<=10; i++) ans = (ans + f[i] * bas[i] % mod) % mod;

printf("%lld\n", ans);

return 0;

}

點分治(樹分治)

將原問題分解成若干相同形式,相互獨立的子問題,各個擊破 一般用來解決有關樹上路徑的統計和詢問 p4178 tree 給定一棵 n 個節點的樹,每條邊有邊權,求出樹上兩點距離小於等於 k 的點對數量。暴力做法 o n2 點分治做法 選擇乙個點作為分治中心,令其為rt做dfs。對於一條路徑path u,...

樹的點分治

codeforces 150e 通過點分治以及合併子樹檢查二分的答案 用深度從小到大的方式可以剪枝,達到nlog 2 n 的複雜度 不離散化常數巨大,離散化常數依然巨大 include include include include include define maxn 100005 define...

Tree(樹分治 點分治)

原題 poj 1741 題意 有一棵n個節點的樹,每條邊都有乙個權值,問有多少個節點之間的距離小於等於k,解析 典型的樹分治,對於每一棵樹,我們首先找到它的重心 重心 一棵樹中以這個點為root時的最大子樹的節點數最小 int siz n maxn n 這棵子樹大小,最大子樹大小 void getg...