異或的路徑 樹形DP

2021-10-02 20:12:51 字數 1639 閱讀 4836

給一棵 n 個點的樹,1 號節點為根,邊有邊權,令 f(u,v) 表示 u 節點到 v 節點,路徑上邊權異或值。求 ∑i=1n∑j=1nf(i,j)\sum_^\sum_^ f(i,j)∑i=1n​∑j=1n​f(i,j),結果對 1000000007 取模。

第一行乙個整數 n(n≤100000)n(n \leq 100000)n(n≤100000),接下來 n-1 行,第 i 行輸入兩個整數,p[i](p[i] < i), v[i](100000>=v[i]>=1)   (分別表示 i+1號節點的父親,以及 i+1 與 p[i] 相連的邊的權值。
輸出乙個整數表示答案。
所以,很容易去往樹形dp上去想,求出每一位對應的在子樹方向上的貢獻,然後通過異或的性質是對每一位進行這樣操作的,所以直接推個樹形dp即可維護。

#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 ll mod = 1e9 + 7;

const int maxn = 1e5 + 7;

int n, head[maxn], cnt;

struct eddge

}edge[maxn];

inline void addeddge(int u, int v, int w)

int siz[maxn][17], xor[maxn], son[maxn];

ll ans[17] = ;

void dfs(int u)

for(int i=head[u], v; ~i; i=edge[i].nex)

son[u] += son[v];

}}inline void init()

int main()

dfs(1);

ll sum = 0, now = 1;

for(int i=0; i<=16; i++)

printf("%lld\n", sum * 2ll % mod);

return 0;}/*

31 1

2 2ans:12

*/

異或生成樹(樹形dp)

傳送門 題意 給定n nn個結點的權值ai 1 127 a i in 1,127 ai 1 127 求最大異或和生成樹。思路 答案的範圍為 0,127 0,127 0,127 考慮樹形dpdp dp,設dp i j dp i j dp i j 為以結點i ii為根的子樹答案是否為jjj 對於當前結點...

異或的路徑

思路 dfs處理出根節點到全部節點的異或值,然後對每一位二進位制計算貢獻 第i位就是2 i的貢獻,而貢獻的數量就是0和1的數量積,因為只有端點是0和1路徑異或後才是1,該位才會1 最好乘二是終起點可以調換 include include include include include include...

最長異或路徑

題目鏈結 戳我前置知識 什麼是異或?如果二進位制下同一位不相同,則為 1 否則為 0 trie樹 基本位運算 對於同一條邊異或兩次,相當於沒有進行異或,我們將dis i 表示為從i點到根節點的路徑異或和。則問題轉化為了求兩點的dis異或最大值 貪心的想,對於乙個數x,我們對於dis i x最大,則每...