題意:紫妹和幽香是17歲的少女,喜歡可愛的東西。
解:動態點分治怎麼搞啊......
一開始想的是權值的限制直接外層權值線段樹就行了,關鍵是怎麼批量求距離。
jxl想的是樹上莫隊的方法,括號序列。然後發現當x和y在不同子樹的時候,x -> lca的距離是負的。
然後考慮lca。距離是d[x] + d[y] - 2d[lca],前面兩個都好求,主要是第三項。
稍稍思考一下,lca只可能是x到根路徑上的點。每個點作為lca的次數就是siz - siz[son]
所以可以轉為計算每條邊的貢獻。每條邊的貢獻就是它下面的子樹大小。這樣就可以做了。
具體來說,d[x] * cnt和∑d[y]可以用兩個字首和陣列求出。以離散化後的權值為下標。
然後建乙個以權值為版本的主席樹,線段樹上維護的是dfs序的該點的父邊的計算次數。
可以發現,按照權值我們每插入乙個點,就要對它到根的路徑進行修改。查詢的時候也是查詢x到根的路徑。所以我們必須寫樹剖了》_<
主席樹區間加區間查,使用標記永久化。
然後發現我之前以為的標記永久化都是假的......
具體來說,給乙個區間加的時候,它途中經過的區間都要加上相應的值,而標記只打在最後的區間。
查詢的時候,沿途記錄標記數量。到終點的時候,用終點的sum + 區間val * 標記數量即可。
如果修改在查詢上面,那麼你會把標記記錄下來,最後在終點區間加上。
如果修改在下,那麼你終點區間的sum已經加了那一次修改的影響。
然後這道毒瘤sb題就這樣a了...時間複雜度nlog2n。
1 #include 2 #include 3ac**4 typedef long
long
ll;5
const
int n = 150010, lm = 1e9, m = 30000010;6
7struct
edge edge[n << 1]; int
tp;10
11struct
node
16}node[n];
1718
inte[n], n, top[n], son[n], fa[n], pos[n], num, siz[n], x[n], deep[n], sum[n], id[n], val2[n], tot, rt[n], val[n];
19ll val[m], d[n], exval[n];
20int
ls[m], rs[m], exsum[n], tag[m];
2122 inline void add(int x, int y, int
z) 30
31void dfs_1(int x, int f)
40 d[y] = d[x] +edge[i].len;
41 val2[y] =edge[i].len;
42dfs_1(y, x);
43 siz[x] +=siz[y];
44if(siz[y] >siz[son[x]]) 47}
48return;49
}5051void dfs_2(int x, int f)
58for(int i = e[x]; i; i =edge[i].nex)
63dfs_2(y, y);64}
65return;66
}6768void add(int x, int &y, int l, int r, int l, int
r) 77 val[y] += sum[std::min(r, r)] - sum[std::max(l, l) - 1
];78
//printf("val %d = %lld += (%d %d) %d \n", y, val[y], std::min(r, r), std::max(l, l) - 1, sum[std::min(r, r)] - sum[std::max(l, l) - 1]);
79if(l <= l && r <=r)
83int mid = (l + r) >> 1;84
if(l <=mid)
87if(mid
90return;91
}9293 inline void insert(int x, int
id)
99return
;100
}101
102 ll ask(int x, int y, int l, int r, int l, int r, int tagx, int
tagy)
106 tagx +=tag[x];
107 tagy +=tag[y];
108int mid = (l + r) >> 1
;109 ll ans = 0
;110
if(l <=mid)
113if(mid
116return
ans;
117}
118119 ll ask(int l, int r, int
x) 126
return
ans;
127}
128129
intmain()
142for(int i = 1, x, y, z; i < n; i++)
147//
prework
148149 dfs_1(1, 0
);150 dfs_2(1, 1
);151 std::sort(x + 1, x + n + 1
);152
int temp = std::unique(x + 1, x + n + 1) - x - 1
;153
for(int i = 1; i <= n; i++)
159for(int i = 1; i <= temp; i++)
163for(int i = 1; i <= n; i++)
166 std::sort(node + 1, node + n + 1
);167
for(int i = 1; i <= n; i++)
170171 ll lastans = 0
;172
for(int i = 1, x, y, z; i <= q; i++)
179 l = std::lower_bound(x + 1, x + temp + 1, l) -x;
180 r = std::upper_bound(x + 1, x + temp + 1, r) - x - 1
;181
if(l >r)
185else
191}
192193
return0;
194 }
P3241 HNOI2015 開店 動態點分治
風見幽香有乙個好朋友叫八雲紫,她們經常一起看星星看月亮從詩詞歌賦談到人生哲學。最近她們靈機一動,打算在幻想鄉開一家小店來做生意賺點錢。這樣的想法當然非常好啦,但是她們也發現她們面臨著乙個問題,那就是店開在 面向什麼樣的人群。很神奇的是,幻想鄉的地圖是乙個樹形結構,幻想鄉一共有 n 個地方,編號為 1...
洛谷P5049 洛谷P5022 題解 旅行
原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...
洛谷練習P2279 P1346
2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...