日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【树状数组】【dfs】树

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【树状数组】【dfs】树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意:

有一棵樹,當給一個點加上一個val時,他的兒子會減val,而他兒子的兒子會加上val(-(-val)=val),有m條指令,要不輸出某個點的值,要不給某個點加值

原題:

題目描述

小L非常喜歡樹。最近,他發現了一棵有趣的樹。這棵樹有n個節點(1到n編號),節點i有一個初始的權值ai。這棵樹的根是節點1。
這棵樹有一個特殊的性質:當你給節點i的權值加 val 的時候,節點i的所有兒子的權值都會加 -val。注意當你給節點i的兒子的權值加 -val 時,節點i的這個兒子的所有兒子的權值都會加 -(-val),以此類推。樣例說明可以很好地幫助你理解這個性質。
有2種操作:
操作(a).“1 x val”表示給節點x的權值加val。
操作(b).“2 x”輸出節點x當前的權值。
為了幫助小L更好地理解這棵樹,你必須處理m個操作。

輸入

第一行包含2個整數n和m。
第二行包含n個整數a1,a2,…,an(1≤ai≤1000)。
接下來的n-1行,每行兩個整數u和v(1≤u接下來的m行,每行包含2種操作的一種。每個操作都保證1≤x≤n,1≤val≤1000。

輸出

對于每個操作(b),輸出一個整數,表示節點x當前的權值。

輸入樣例

5 5 1 2 1 1 2 1 2 1 3 2 4 2 5 1 2 3 1 1 2 2 1 2 2 2 4

輸出樣例

3 3 0

說明

【輸入輸出樣例說明】

初始各個節點的權值依次為[1,2,1,1,2]。
第一個操作給節點2的權值增加3,會給節點2的兒子4、5的權值增加-3。此時各個節點的權值變成[1,5,1,-2,-1]。
第二個操作給節點1的權值增加2,會給節點1的兒子2、3的權值增加-2,然后會給節點2的兒子4、5的權值增加-(-2)。各個節點的權值變成[3,3,-1,0,1]。

【數據說明】

對于50%的數據,1≤n≤2000,1≤m≤2000。
對于100%的數據,1≤n≤100000,1≤m≤100000。

解題思路

80分思路1:

當給某個點加值時,dfs下去,要輸出時,直接輸出

#include<cstdio> using namespace std; int n,m,x,y,z,b[100005],head[100005]; struct rec {int to,next; }a[100005]; void dfs(int now,int d) {b[now]+=d;//相加for (int i=head[now];i;i=a[i].next)//子節點dfs(a[i].to,-d);//數字翻轉 } int main() {scanf("%d %d",&n,&m);for (int i=1;i<=n;++i)scanf("%d",&b[i]);for (int i=1;i<n;++i){scanf("%d %d",&x,&y);a[i].to=y;//存儲a[i].next=head[x];head[x]=i;}for (int i=1;i<=m;++i){scanf("%d %d",&y,&x);if (y==2){printf("%d\n",b[x]);//輸出continue;}scanf("%d",&z);//輸入dfs(x,z);//dfs下去} }

80分思路2:

給某個點價值時,先存下來,等輸出時,再往父節點搜

#include<cstdio> using namespace std; int n,m,x,y,z,b[100005],dad[100005],zj[100005]; int dfs(int dep,int now) {if (!dep) return 0;//搜完了return zj[dep]*now+dfs(dad[dep],-now);//繼續往上 } int main() {scanf("%d %d",&n,&m);for (int i=1;i<=n;++i)scanf("%d",&b[i]);for (int i=1;i<n;++i){scanf("%d %d",&x,&y);dad[y]=x;//記錄父節點}for (int i=1;i<=m;++i){scanf("%d %d",&x,&y);if (x&1)//加值{scanf("%d",&z);zj[y]+=z;//記錄起來continue;}printf("%d\n",b[y]+dfs(y,1));//往父節點搜} }

正解

按奇偶性分下類
然后樹狀數組修改即可(懶)

總結

以上是生活随笔為你收集整理的【树状数组】【dfs】树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。