1. 程式人生 > >bzoj3924: [Zjoi2015]幻想鄉戰略遊戲 //動態點分治

bzoj3924: [Zjoi2015]幻想鄉戰略遊戲 //動態點分治

題意

給出一棵N(<=1e5)個點的樹。
特殊性質:每個點度數不超過20。
M(<=1e5)次操作,支援更改一個點的點權,每次操作後輸出∑(每個點的點權*該點到帶權重心距離)。

題解

關於找帶權重心:
規定sum[i]表示點i子樹的點權和。
如果當前在x,重心在son[x]的子樹裡,當且僅當sum[x]<2*sum[son[x]]
然後我們直接走過去就可以了。
多個重心的話 這樣說好像並不嚴謹 算了感性理解吧
我們點分一發。
查詢的時候從分治根開始走,枚一下所有出邊。
如果發現當前重心在該邊指向的分治子樹裡,就走到分治子樹根的位置,重複上述過程。
這個複雜度是log*20的。
答案怎麼統計呢?
從x向其相連的y所在子樹走的時候,把x子樹中除y所在子樹外的點權壓到y上。
這一步和直接修改點權的更新一樣 都是log的。
所以就是O(nlog^2n+nlogn*20)

程式碼

#include<bits/stdc++.h>
#define N 100005
#define L 17
using namespace std;
typedef long long ll;
int n,m,w,rt,dep[N][L],f[N],siz[N],dp[N],ch[N<<1],
to[N<<1],hd[N<<1],lk[N],len[N<<1],stu[L],stv[L],stw[L],tot,cnt;
ll mul[N],sum[N],de[N],ans,tmp;
bool vis[N];
void
ini(int x,int lst) { siz[x]=1; for(int k,i=lk[x];i;i=hd[i]) if((k=to[i])^lst) ini(k,x),siz[x]+=siz[k]; } void dfs(int x,int y,int l) { siz[x]=1; for(int k,i=lk[x];i;i=hd[i]) if(((k=to[i])^y)&&!vis[k]) dep[k][l]=dep[x][l]+len[i], dfs(k,x,l),siz[x]+=siz[k]; } int
getr(int x,int y,int nn) { for(int k,i=lk[x];i;i=hd[i]) if(((k=to[i])^y)&&siz[k]>nn&&!vis[k]) return getr(k,x,nn); return x; } int build(int x,int fa) { vis[x=getr(x,x,siz[x]>>1)]=1; if(fa)dp[x]=dp[f[x]=fa]+1; dfs(x,x,dp[x]); for(int i=lk[x];i;i=hd[i]) if(!vis[to[i]]) ch[i]=build(to[i],x); return x; } inline void upd(int u,int v,int y) { for(int i=u;;i=f[i]) { sum[i]+=v,mul[i]+=(ll)v*dep[u][dp[i]]; if(f[i]==y)break; de[i]+=(ll)v*dep[u][dp[i]-1]; } } inline void add(int u,int v) {to[++cnt]=v,hd[cnt]=lk[u],len[cnt]=w,lk[u]=cnt;} int u,v; int main() { scanf("%d%d",&n,&m); for(int i=1;i<n;i++) scanf("%d%d%d",&u,&v,&w), add(u,v),add(v,u); ini(1,0),rt=build(1,0); while(m--) { scanf("%d%d",&u,&v); upd(u,v,0); tot=tmp=0; for(int i=rt;;) { tmp+=mul[u=i]; for(int k,j=lk[i];j;j=hd[j]) if((k=ch[j])&&sum[i]<(sum[k]<<1)) { tmp+=(sum[i]-sum[k])*len[j]-de[k]; upd(stu[tot]=to[j],stv[tot]=sum[i]-sum[k],stw[tot]=i),tot++; i=k; } if(u==i)break; } printf("%lld\n",tmp); while(tot--) upd(stu[tot],-stv[tot],stw[tot]); } }

相關推薦

BZOJ3924: [Zjoi2015]幻想戰略遊戲(動態分治)

Description  傲嬌少女幽香正在玩一個非常有趣的戰略類遊戲,本來這個遊戲的地圖其實還不算太大,幽香還能管得過來,但是不知道為什麼現在的網遊廠商把遊戲的地圖越做越大,以至於幽香一眼根本看不過來,更別說和別人打仗了。 在打仗之前,幽香現在面臨一個非常基本的管理問題需要解決。&

bzoj3924: [Zjoi2015]幻想戰略遊戲 //動態分治

題意 給出一棵N(<=1e5)個點的樹。 特殊性質:每個點度數不超過20。 M(<=1e5)次操作,支援更改一個點的點權,每次操作後輸出∑(每個點的點權*該點到帶權重心距離)。 題解 關於找

[ZJOI2015]幻想戰略遊戲——動態分治

[ZJOI2015]幻想鄉戰略遊戲 帶修改下,邊點都帶權的重心隨著變動的過程中,一些子樹內的點經過會經過一些公共邊。考慮能不能對這樣的子樹一起統計。把樹上貢獻分塊。考慮點分治演算法不妨先把題目簡化一下:假設沒有修改,多次詢問,每次給定一個s,求$\sum d_v*dis(s,v)$為了讓一塊可以一起統計,我

bzoj 3924 [Zjoi2015]幻想戰略遊戲——動態分治(暴力移動找重心)

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 度數只有20,所以從一個點暴力列舉其出邊,就能知道往哪個方向走。 知道方向之後直接走到點分樹的那個部分的兒子上,即一下走到了那個方向的重心。這樣只會走 log 次。 需要通過點分樹上維護的資

P3345 [ZJOI2015]幻想戰略遊戲 動態分治

\(\color{#0066ff}{ 題目描述 }\) 傲嬌少女幽香正在玩一個非常有趣的戰略類遊戲,本來這個遊戲的地圖其實還不算太大,幽香還能管得過來,但是不知道為什麼現在的網遊廠商把遊戲的地圖越做越大,以至於幽香一眼根本看不過來,更別說和別人打仗了。 在打仗之前,幽香現在面臨一個非常基本的管理問題需要解

bzoj 3924 幻想戰略遊戲 —— 動態分治

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 參考了部落格:https://blog.csdn.net/qq_34564984/article/details/53791482 然後感覺這題其實是很好想的,為了計算答案而維護答案、權值和以

bzoj3924 [Zjoi2015]幻想戰略遊戲 分樹,動態

stream print 無法 經濟 -- body del 分數 int 【BZOJ3924】[Zjoi2015]幻想鄉戰略遊戲 Description 傲嬌少女幽香正在玩一個非常有趣的戰略類遊戲,本來這個遊戲的地圖其實還不算太大,幽香還能管得過來,但是不知道為

bzoj3924 [Zjoi2015]幻想戰略遊戲動態分治

就是求帶權重心,可以修改點權。 我們首先建出重心樹。對於每個節點x記 s1[x]–x的子樹到x的答案, s2[x]–x的子樹的點權和, s3[x]–x的子樹到fa[x]的答案。 那我們就可以通過這些資訊得出以x為重心的答案(在重心樹上一直往上跳,複雜度

[BZOJ3924][Zjoi2015]幻想戰略遊戲動態分治

看到資料範圍和6s的時限,得(cai)出是一道動態點分治。 這道題有一個巧妙的思路: 假設當前補給站為uu,並強制以uu為根,vv為uu的一個子節點,sumdusumdu和sumdvsumdv分別為uu的子樹內的dd之和以及vv的子樹內的dd之和,len(u

luogu P3345 [ZJOI2015]幻想戰略遊戲分樹)

names ear long clas 信息 圖片 log 理解 節點 題意自己看。。。 思路 沒想到今(昨)天刷著刷著點分治的水題,就刷出來了一個點分樹。。。 然後就瘋狂地找題解,代碼,最後終於把它給弄懂了。 點分樹——動態點分治,對於此題來說,我們發現設u為當前的補給站

BZOJ3924: [Zjoi2015]幻想戰略遊戲

math != i+1 bzoj3924 class val log 有一個 har BZOJ3924: [Zjoi2015]幻想鄉戰略遊戲 https://lydsy.com/JudgeOnline/problem.php?id=3924 分析: 首先有一個很棒的思路,

BZOJ3924幻想戰略遊戲動態分治

truct 產生 。。 sum 遊戲 stream str pos struct 【BZOJ3924】幻想鄉戰略遊戲(動態點分治) 題面 權限題。。。(窮死我了) 洛谷 題解 考慮不修改 發現一個貪心的做法 假設當前放在當前位置 如果它有一個子樹的兵的總數大於總數的一半 那

LOJ #2135. 「ZJOI2015幻想戰略遊戲分樹)

題意 給你一顆 \(n\) 個點的樹,每個點的度數不超過 \(20\) ,有 \(q\) 次修改點權的操作。 需要動態維護帶權重心,也就是找到一個點 \(v\) 使得 \(\displaystyle \sum_{v} w_v \times \mathrm{dist}(u, v)\) 最小。 \(n \le 1

【BZOJ 3924】[Zjoi2015]幻想戰略遊戲

upd += num ffffff esp image 優化 color 代碼 題目:    題解:   對點分樹理解加深了233,膜拜zzh幹翻紫荊花。   感謝zzh的講解。   首先優化基於傳統DP,假設樹不發生變化,我們就可以利用DP求出帶權重心。   

bzoj 3924: [Zjoi2015]幻想戰略遊戲

oid main 距離 esp space 當前 路徑 但是 std Description 傲嬌少女幽香正在玩一個非常有趣的戰略類遊戲,本來這個遊戲的地圖其實還不算太大,幽香還能管得過來,但是不知道為什麽現在的網遊廠商把遊戲的地圖越做越大,以至於幽香一眼根本看不過來,更別

[ZJOI2015]幻想戰略遊戲

[ZJOI2015]幻想鄉戰略遊戲 動態點分治   題目連結:https://www.luogu.org/problemnew/show/P3345   參考:https://www.luogu.org/blog/zcysky/solution-p3345   首先對於點分治下去的重心,我們

luogu_P3345[zjoi2015]幻想戰略遊戲

傳送門 Description 傲嬌少女幽香正在玩一個非常有趣的戰略類遊戲,本來這個遊戲的地圖其實還不算太大,幽香還能管得過來,但是不知道為什麼現在的網遊廠商把遊戲的地圖越做越大,以至於幽香一眼根本看不過來,更別說和別人打仗了。 在打仗之前,幽香現在面臨一個非常基本的管理問題需要解決

ZJOI 2015 幻想戰略遊戲動態分治

題意 https://loj.ac/problem/2135 思路 首先要明確一點,答案分佈是有單調性的。什麼意思呢?假設我們的答案在 \(u\) 節點,\((u,v)\) 之間有一條邊且 \(u\) 離答案所在的點更近,那麼 \(u\) 節點作為答案一定不比在 \(v\) 節點作答案劣。從鏈的角度分析

bzoj3924&&luogu3345】幻想戰略遊戲

roo 當前 def 目前 style %d col ext continue 這題可以用線段樹做,不過正解恐怕是動態點分治?(點分樹) 簡單介紹下動態點分治的概念:在點分治的過程中,一般我們面對的問題都是靜態的。如果涉及到修改這類的操作,我們就希望找到我們是如何處理到當前

LOJ #2135. 「ZJOI2015幻想戰略遊戲

dep turn name 如何 zjoi return ace queue oid #2135. 「ZJOI2015」幻想鄉戰略遊戲 鏈接 分析:   動態點分治,求加權重心,帶修改。   考慮如果知道了一個點s,如何求答案,那麽首先可以點分治的思想,求每