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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

bzoj 3730 震波

發(fā)布時(shí)間:2024/1/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 3730 震波 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

給一個(gè) $n$ 個(gè)點(diǎn)的帶權(quán)樹(shù),每次修改一個(gè)點(diǎn)的權(quán)值,或者詢問(wèn)到 $x$ 距離不超過(guò) $k$ 的點(diǎn)的權(quán)值和,強(qiáng)制在線

sol:

套路題,首先搞出一個(gè)點(diǎn)分樹(shù),每個(gè)重心,以到重心的距離為下標(biāo),點(diǎn)權(quán)為權(quán)值建兩棵線段樹(shù),一個(gè)用來(lái)統(tǒng)計(jì)答案,一個(gè)用來(lái)消除對(duì)父節(jié)點(diǎn)的影響

每次修改和訊詢問(wèn)都是暴力爬樹(shù)高,在經(jīng)過(guò)的每棵線段樹(shù)里修改就可以了

?

好了,然后我們來(lái) $D$ 這個(gè) sb 博主

道理我都懂,你求 LCA 為什么要樹(shù)剖啊,復(fù)雜度強(qiáng)行加 log

明明樹(shù)狀數(shù)組就可以干的事情(單點(diǎn)加,區(qū)間和)你為什么要線段樹(shù)啊,強(qiáng)行多大常數(shù)

OYJason 8160ms 就能過(guò)的題強(qiáng)行被我搞到了 13796ms

我真是個(gè) sb

復(fù)雜度大概是 $O(nlogn + mlog^2n)$ ?

#include<bits/stdc++.h> #define LL long long using namespace std; inline int read() {int x = 0,f = 1;char ch = getchar();for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';return x * f; } const int maxn = 500010; int n,m,lastans; int first[maxn],to[maxn << 1],nx[maxn << 1],cnt; inline void add(int u,int v){to[++cnt] = v;nx[cnt] = first[u];first[u] = cnt;} inline void ins(int u,int v){add(u,v);add(v,u);} namespace LCA //RMQ is not good ? {int dep[maxn],bl[maxn],fa[maxn],size[maxn];inline void dfs1(int x){size[x] = 1;for(int i=first[x];i;i=nx[i]){if(to[i] == fa[x])continue;fa[to[i]] = x;dep[to[i]] = dep[x] + 1;dfs1(to[i]);size[x] += size[to[i]];}}inline void dfs2(int x,int col){int k = 0;bl[x] = col;for(int i=first[x];i;i=nx[i])if(dep[to[i]] > dep[x] && size[to[i]] > size[k])k = to[i];if(!k)return;dfs2(k,col);for(int i=first[x];i;i=nx[i])if(dep[to[i]] > dep[x] && to[i] != k)dfs2(to[i],to[i]);}inline int lca(int x,int y){while(bl[x] != bl[y]){if(dep[bl[x]] < dep[bl[y]])swap(x,y);x = fa[bl[x]];}return dep[x] > dep[y] ? y : x;} } namespace SEG {int root[maxn][2],ls[maxn << 4],rs[maxn << 4],val[maxn << 4],size;inline void Insert(int &x,int l,int r,int pos,int va){if(!x) x = ++size;val[x] += va;if(l == r)return;int mid = (l + r) >> 1;if(pos <= mid)Insert(ls[x],l,mid,pos,va);else Insert(rs[x],mid + 1,r,pos,va);}inline int query(int x,int l,int r,int L,int R){if(!x)return 0;if(L <= l && r <= R)return val[x];int mid = (l + r) >> 1,ans = 0;if(L <= mid)ans += query(ls[x],l,mid,L,R);if(R > mid)ans += query(rs[x],mid + 1,r,L,R);return ans;} } inline int q_dis(int x,int y){return LCA::dep[x] + LCA::dep[y] - (LCA::dep[LCA::lca(x,y)] << 1);} int size[maxn],f[maxn],vis[maxn],d[maxn],v[maxn],son,root; int nfa[maxn]; inline void solve(int rt,int type,int x,int fa) {SEG::Insert(SEG::root[rt][type],0,n,d[x],v[x]);for(int i=first[x];i;i=nx[i]){if(to[i] == fa || vis[to[i]])continue;d[to[i]] = d[x] + 1;solve(rt,type,to[i],x);} } inline void getroot(int x,int fa) {size[x] = 1,f[x] = 0;for(int i=first[x];i;i=nx[i]){if(to[i] == fa || vis[to[i]])continue;getroot(to[i],x);size[x] += size[to[i]];f[x] = max(f[x],size[to[i]]);}f[x] = max(f[x],son - size[x]);if(f[x] < f[root])root = x; } inline void work(int x) {vis[x] = 1;d[x] = 0;solve(x,0,x,0);for(int i=first[x];i;i=nx[i]){if(vis[to[i]])continue;son = size[to[i]];root = 0;d[to[i]] = 1;getroot(to[i],0);solve(root,1,to[i],x);nfa[root] = x;work(root);} } inline int query(int x,int k) {int ret = SEG::query(SEG::root[x][0],0,n,0,k);for(int i=x;nfa[i];i = nfa[i]){int du = q_dis(x,nfa[i]);ret += SEG::query(SEG::root[nfa[i]][0],0,n,0,k - du);ret -= SEG::query(SEG::root[i][1],0,n,0,k - du); }return ret; } inline void update(int x,int k) {int delt = k - SEG::query(SEG::root[x][0],0,n,0,0);SEG::Insert(SEG::root[x][0],0,n,0,delt);for(int i=x;nfa[i];i = nfa[i]){int du = q_dis(x,nfa[i]);SEG::Insert(SEG::root[nfa[i]][0],0,n,du,delt);SEG::Insert(SEG::root[i][1],0,n,du,delt);} } int main() {//freopen("1.in","r",stdin);//freopen("1w.out","w",stdout);n = read(),m = read();for(int i=1;i<=n;i++)v[i] = read();for(int i=2;i<=n;i++){int u = read(),v = read();ins(u,v);}LCA::dfs1(1);LCA::dfs2(1,1);f[0] = son = n;getroot(1,0);work(root);while(m--){int opt = read(),x = read() ^ lastans,y = read() ^ lastans;if(opt)update(x,y);else printf("%d\n",lastans = query(x,y));} } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/Kong-Ruo/p/9913848.html

總結(jié)

以上是生活随笔為你收集整理的bzoj 3730 震波的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。