แนวคิด
สำหรับต้นไม้ที่มีโหนด m และจำนวนที่เกี่ยวข้องกับทุกโหนด เราสามารถทำลายขอบต้นไม้ใดๆ ก็ได้ ซึ่งจะส่งผลให้เกิดต้นไม้ใหม่ 2 ต้น ในที่นี้ เราต้องนับจำนวนขอบในลักษณะนี้เพื่อให้ Bitwise OR ของโหนดที่มีอยู่ในต้นไม้สองต้นที่สร้างขึ้นหลังจากทำลายขอบนั้นเท่ากัน ควรสังเกตว่าค่าของทุกโหนดคือ ≤ 10^6
อินพุต
values[]={1, 3, 1, 3} 1 / | \ 2 3 4
ผลลัพธ์
2
ที่นี่ ขอบระหว่าง 1 ถึง 2 สามารถหักได้ Bitwise OR ของต้นไม้สองต้นที่ได้จะเป็น 3
ในทำนองเดียวกัน ขอบระหว่าง 1 ถึง 4 ก็หักได้เช่นกัน
วิธีการ
ในที่นี้ ปัญหาดังกล่าวสามารถแก้ไขได้โดยใช้ DFS อย่างง่าย (Depth First Search) เนื่องจากค่าของโหนดคือ ≤ 10^6 จึงสามารถแสดงการนำไบนารี 22 บิตไปใช้จริงได้ ด้วยเหตุนี้ Bitwise OR ของค่าของโหนดจึงสามารถแสดงเป็นไบนารีบิตได้ 22 บิตในที่นี้ วิธีการคือการกำหนดจำนวนครั้งที่แต่ละบิตถูกตั้งค่าในค่าทั้งหมดของ assub-tree สำหรับแต่ละขอบ เราจะตรวจสอบด้วยความเคารพของแต่ละบิตตั้งแต่ 0 ถึง 21 ตัวเลขที่มีบิตเฉพาะตามที่กำหนดเป็นศูนย์ทั้งในต้นไม้ที่เป็นผลลัพธ์หรือสูงกว่าศูนย์ในต้นไม้ผลลัพธ์ทั้งสองและหากเห็นว่าเป็นไปตามเงื่อนไข สำหรับบิตทั้งหมด ขอบนั้นจะถูกนับในผลลัพธ์
ตัวอย่าง
// C++ implementation of the approach #include<bits/stdc++.h> using namespace std; int m1[1000],x1[22]; // Uses array to store the number of times each bit // is set in all the values of a subtree int a1[1000][22]; vector<vector<int>> g; int ans1 = 0; // Shows function to perform simple DFS void dfs(int u1, int p1){ for (int i=0;i<g[u1].size();i++) { int v1 = g[u1][i]; if (v1 != p1) { dfs(v1, u1); // Determining the number of times each bit is set // in all the values of a subtree rooted at v for (int i = 0; i < 22; i++) a1[u1][i] += a1[v1][i]; } } // Verifying for each bit whether the numbers // with that particular bit as set are // either zero in both the resulting trees or // greater than zero in both the resulting trees int pp1 = 0; for (int i = 0; i < 22; i++) { if (!((a1[u1][i] > 0 && x1[i] - a1[u1][i] > 0) || (a1[u1][i] == 0 && x1[i] == 0))) { pp1 = 1; break; } } if (pp1 == 0) ans1++; } // Driver code int main(){ // Number of nodes int n1 = 4; // int n1 = 5; // Uses ArrayList to store the tree g.resize(n1+1); // Uses array to store the value of nodes m1[1] = 1; m1[2] = 3; m1[3] = 1; m1[4] = 3; /* m1[1] = 2; m1[2] = 3; m1[3] = 32; m1[4] = 43; m1[5] = 8;*/ //Uses array to store the number of times each bit // is set in all the values in complete tree for (int i = 1; i <= n1; i++) { int y1 = m1[i]; int k1 = 0; // Determining the set bits in the value of node i while (y1 != 0) { int p1 = y1 % 2; if (p1 == 1) { x1[k1]++; a1[i][k1]++; } y1 = y1 / 2; k1++; } } // push_back edges g[1].push_back(2); g[2].push_back(1); g[1].push_back(3); g[3].push_back(1); g[1].push_back(4); g[4].push_back(1); //g[1].push_back(5); //g[5].push_back(1); dfs(1, 0); cout<<(ans1); }
ผลลัพธ์
2