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,如何求答案,那麽首先可以點分治的思想,求每