description
"奮戰三星期,造台計算機"。小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並不知道它的答案是否正確,你能幫助他嗎?
solution
分塊。塊內直接統計,單點的sum樹狀陣列暴力加起來
為了方便修改,g[a][i]表示點a對塊[i]的貢獻
另外,好坑啊這題會爆long long
#include#include#include
#include
#include
#define maxn 100007
using
namespace
std;
typedef unsigned
long
long
ll;int n,m,init,num,head[maxn],g[maxn][330],cnt=0
;ll c[maxn],d[maxn],sum[maxn],blocks[
330];
int dfn_clock=0,in[maxn],out
[maxn],a[maxn];
ll read()
while(c>='
0'&&c<='9'
)
return x*f;
}struct
node
edges[maxn*2
];void addedge(int u,int
v)int lowbit(int x)
void add(int pos,intx)}
ll query(
intpos)
return
res;
}void dfs(int u,int
f) blocks[(u-1)/init]+=sum[u];
out[u]=dfn_clock;
a[(u-1)/init]--;
}void change(int a,int
b)void query(int a,int
b) printf(
"%llu\n
",res);
}int
main()
addedge(u,v);
addedge(v,u);
}dfs(root,0);
for(int i=1;i<=n;i++)
add(
in[i],d[i]);
for(int i=1;i<=m;i++)
return0;
}
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 普通計算姬
求樹上一段連續編號的子樹大小的和,帶修改。分塊。預處理乙個東西g x i 表示x這個點對i這個塊的影響。然後就可以暴力搞了。對於零散的點,就用樹狀陣列維護dfs序的區間和。貌似是nn logn 的,不過就是能過。還有以後打 盡量注意,少遞迴,少遞迴,少遞迴!最後要用un sign edlo nglo...
BZOJ 4765 普通計算姬
bzoj 4765 普通計算姬 分塊 奮戰三星期,造台計算機 小g響應號召,花了三小時造了臺普通計算姬。普通計算姬比普通計算機要厲害一些 普通計算機能計算數列區間和,而普通計算姬能計算樹中子樹和。更具體地,小g的計算姬可以解決這麼個問題 給定一棵n個節點的帶權樹,節點編號為1到n,以root為根,設...