朋友(翻轉樹邊權值比賽) 依然是思維

2022-04-12 06:01:59 字數 2114 閱讀 5670

b君在圍觀一群男生和一群女生玩遊戲,具體來說遊戲是這樣的:

給出一棵n個節點的樹,這棵樹的每條邊有乙個權值,這個權值只可能是0或1。 在一局遊戲開始時,會確定乙個節點作為根。接下來從女生開始,雙方輪流進行 操作。

當一方操作時,他們需要先選擇乙個不為根的點,滿足該點到其父親的邊權為1; 然後找出這個點到根節點的簡單路徑,將路徑上所有邊的權值翻轉(即0變成1,1 變成0 )。

當一方無法操作時(即所有邊的邊權均為0),另一方就獲得了勝利。

如果在雙方均採用最優策略的情況下,女生會獲勝,則輸出「girls win!」,否則輸 出「boys win!」。

為了讓遊戲更有趣味性,在每局之間可能會有修改邊權的操作,而且每局遊戲指 定的根節點也可能是不同的。

具體來說,修改邊權和進行遊戲的操作一共有m個,具體如下: ∙

'>∙

'>∙

「0 x」表示詢問對於當前的樹,如果以x為根節點開始遊戲,哪方會獲得勝利。 ∙

'>∙

「1 x y z 」表示將x和y之間的邊的邊權修改為z。

b君當然知道怎麼做啦!但是他想考考你。

input包含至多5組測試資料。

第一行有乙個正整數,表示資料的組數。

接下來每組資料第一行,有二個空格隔開的正整數n,m,分別表示點的個數,操 作個數。保證n,m< 40000。

接下來n-1行,每行三個整數x,y,z,表示樹的一條邊。保證1思路:

對於這種類似的題,我們知道一定有隱藏的規律。

主要就是看直接連到根節點的樹邊。

①假如連線到根節點的邊只有一條,我們把這條邊叫作x。

1.那麼我們想,如果x邊權是1:

先手可以不管x後面的邊,只將x翻成0,即使下一步,另一人將後面的可以翻邊翻了,那麼x又變成1了,這樣不管另一人翻後面的哪條邊,先手都可以只翻x,消耗另一人,直至x後面全是0,再翻x,先手勝利。這種方法就是題目中所說的」最優策略「。

2.相反的,x邊權是0:

先手只能翻x後面的邊,而另一人(後手)就可以仿照上一種情況的先手,後手取勝。

②類似的,我們將直接連線到根節點的,且邊權是1的邊拓展到多條,將它們統稱為x:

1.如果x的數量是奇數,先手與後手(一條鏈一條鏈地)輪流消耗對方,最終剩下一條權值是1的x,還是先手先翻x,先手取勝(仿照①1.)

2.同理,x的數量是偶數,先手與後手(一條鏈一條鏈地)輪流消耗對方,最終剩下一條權值是1的x,是後手先翻x,後手取勝(仿照①2.)

注意:(在②中,我們不跟①一樣討論直接連到根節點的,邊權是0的邊,因為如果這條邊後面的邊有權值1,先手翻了之後,

這條直接連到根節點的邊就成1了,後手就可以用其消耗對方,後手勝利,也就相當於x是0條的時候,即x數量是偶數,同②2.結論)

總結:我們只需看與根節點直接相連的邊權權值是1的有幾條,就可判斷以該節點為根節點而開始遊戲的勝者,奇數->先手勝偶數->後手勝

**:

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;

6const

int maxn=4e4+3;7

inthead[maxn],n,m,cnt,key;

8int

x,y,z;

9struct edgee[2*maxn];

10void add(int x,int y,int

z)16

void xiugai(int x,int y,int

z)22}23

for(int i=head[y];i;i=e[i].next)28}

29}30void sta(int

root)

35if(ans%2==1)printf("

girls win!\n");

36else printf("

boys win!\n");

37}38int

main()

49for(int i=1;i<=m;++i)else58}

59}60return0;

61 }

權值BIT 小朋友排隊

解題思路 每個小朋友需要交換的次數必然是左邊比他大的 右邊比他小的 用 權值bit 維護字首字尾再單獨計算等差即可 主席樹應該也是可以解決的 zeolim an ac a day keeps the bug away pragma gcc optimize 2 include include inc...

權值線段樹

維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性k小值,全域性rank,前驅,後繼等。單詞操作時間複雜度為o logn 空間複雜度為o n 相對於平衡樹的優勢 簡單,速度快 劣勢 值域較大時,我們需要離散化,變成離線資料結構 我認為...

權值線段樹

include using namespace std int n,m,tre 10003 4 laz 10003 4 void pushdown int num void update int num,int le,int ri,int x,int y,int z pushdown num int...