BZOJ 4765 分塊 樹狀陣列

2022-03-29 07:59:51 字數 2094 閱讀 7834

傳送門

"奮戰三星期,造台計算機"。小g響應號召,花了三小時造了臺普通計算姬。普通計算姬比普通計算機要厲害一些

。普通計算機能計算數列區間和,而普通計算姬能計算樹中子樹和。更具體地,小g的計算姬可以解決這麼個問題

:給定一棵n個節點的帶權樹,節點編號為1到n,以root為根,設sum[p]表示以點p為根的這棵子樹中所有節點的權

值和。計算姬支援下列兩種操作:

1 給定兩個整數u,v,修改點u的權值為v。

2 給定兩個整數l,r,計算sum[l]+sum[l+1]+....+sum[r-1]+sum[r]

儘管計算姬可以很快完成這個問題,可是小g並不知道它的答案是否正確,你能幫助他嗎?

剛看到這題想到樹剖套線段樹的做法,但是時間複雜度太大,無法接受。既然用log級的資料結構無法維護,很容易想到分塊。按節點編號分塊,每個塊維護sum[l]+sum[l+1]+...+sum[r],[l,r]為塊邊界

這道題的突破口是考慮每個節點的貢獻

對於每個節點u來說,它的值被改為v,只會影響u的祖先節點的子樹和。

因此可以分塊預處理\(f[i][j]\)表示第i個節點有多少個祖先節點在第j個塊裡面。dfs的時候維護乙個陣列cnt[i]儲存當前搜尋樹中有多少個節點在第i塊中,遞迴到某個節點x時cnt[x]++,回溯時cnt[x]--,這樣\(f[x][i]=cnt[i]\)

那麼如果某個節點x的值增加了d,我們就遍歷每個塊i,每個塊i的和增加\(f[x][i]\times d\)

查詢的時候整塊可以直接加上和。對於不完整的部分,直接查詢每個節點的子樹和再相加,用dfs序+樹狀陣列的方法維護。樹狀陣列的第i個位置儲存第i個節點的值,查詢子樹和的時候利用dfs序可以\(o(\log n)\)的時間內查詢出第i個節點的子樹和

坑點:此題不能用樹狀陣列,會被卡常。記得開unsigned long long,否則會爆

#include#include#include#include#define maxn 100005

#define maxb 505

#define ll unsigned long long

using namespace std;

int n,m;

struct bit

void update(int x,ll v)

} ll sum(int x)

return ans;

} ll query(int l,int r)

}t;struct edge e[maxn<<1];

int head[maxn];

int esz=1;

void add_edge(int u,int v)

ll a[maxn];

int bsz,bcnt;//塊大小,塊個數

inline int lb(int id)

inline int rb(int id)

int cnt[maxb];//cnt[i]存第i個塊內有多少個當前搜尋樹中的節點

int f[maxn][maxb]; //f[i][j]存第i個塊內有多少個j的祖先節點

ll sum[maxn];//整塊的和

int id[maxn];

int dfnl[maxn],dfnr[maxn];

int tim=0;

void dfs(int x,int fa)

for(int i=head[x]; i; i=e[i].next)

} dfnr[x]=tim;

cnt[id[x]]--;

}void change(int u,ll v)

} ll ask(int l,int r)

for(int i=id[l]+1;iif(id[l]!=id[r])

} return ans;

}int main()

} bsz=sqrt(n);

bcnt=1;

for(int i=1;i<=n;i++)

dfs(root,0);

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)

for(int i=1;i<=m;i++)else

}}

BZOJ 4765 普通計算姬(分塊 樹狀陣列)

description 奮戰三星期,造台計算機 小g響應號召,花了三小時造了臺普通計算姬。普通計算姬比普通計算機要厲害一些 普通計算機能計算數列區間和,而普通計算姬能計算樹中子樹和。更具體地,小g的計算姬可以解決這麼個問題 給定一棵n個節點的帶權樹,節點編號為1到n,以root為根,設sum p 表...

BZOJ4765 普通計算姬(分塊 BIT)

傳送門 其實很簡單 考慮修改乙個點對於所有塊的影響 我們可以預處理出乙個陣列ef i j ef i j ef i j 表示修改i ii對第j jj塊會影響幾個點 顯然只會影響i ii的祖先 這個陣列可以在dfs dfsdf s的時候繼承父親的o n o sqrt n o n 得到 詢問整塊直接返回 ...

bzoj 4765 普通計算姬 分塊 dfs序

time limit 30 sec memory limit 256 mb submit 1502 solved 322 submit status discuss 奮戰三星期,造台計算機 小g響應號召,花了三小時造了臺普通計算姬。普通計算姬比普通計算機要厲害一些 普通計算機能計算數列區間和,而普通...