【LOJ2322】「清華集訓 2017」Hello world!
【題目連結】
【思路要點】
- 一個 以內的數開根 次後一定會變成 ,因此有效的修改次數不會超過 。
- 設定一個閾值 ,若 ,則暴力進行詢問或修改,藉助長鏈剖分求 級祖先,單次操作時間複雜度為 。
- 考慮 的修改,用並查集維護每個點向上 的整數倍步第一個能夠到達的非 的位置,再進行修改,就可以保證找到的位置上的修改有效。並查集大小為 。
- 考慮 的詢問,用 棵樹狀陣列維護子樹和即可快速查詢。
- 時間複雜度 。
【程式碼】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; const int MAXLOG = 18; const int limit = 25; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } struct BinaryIndexTree { int n; ll a[MAXN]; void init(int x) { n = x; memset(a, 0, sizeof(a)); } void modify(int x, ll d) { for (int i = x; i <= n; i += i & -i) a[i] += d; } ll query(int x) { ll ans = 0; for (int i = x; i >= 1; i -= i & -i) ans += a[i]; return ans; } } BIT[limit]; int n, m, highbit[MAXN]; ll val[MAXN]; int depth[MAXN], down[MAXN], son[MAXN], up[MAXN]; int f[MAXN][limit], father[MAXN][MAXLOG]; bool vis[MAXN]; int timer[limit], dfn[MAXN][limit], rit[MAXN][limit]; vector <int> a[MAXN], lst[MAXN][2]; void dfs(int pos, int fa) { depth[pos] = depth[fa] + 1; father[pos][0] = fa; for (int i = 1; i < MAXLOG; i++) father[pos][i] = father[father[pos][i - 1]][i - 1]; for (unsigned i = 0; i < a[pos].size(); i++) if (a[pos][i] != fa) { dfs(a[pos][i], pos); if (down[a[pos][i]] > down[pos]) { down[pos] = down[a[pos][i]]; son[pos] = a[pos][i]; } } down[pos]++; } void efs(int pos, int fa, int from) { up[pos] = from; if (from == pos) { for (int i = pos; i; i = son[i]) lst[pos][1].push_back(i); for (int i = pos; i; i = father[i][0]) lst[pos][0].push_back(i); } if (son[pos]) efs(son[pos], pos, from); for (unsigned i = 0; i < a[pos].size(); i++) if (a[pos][i] != fa && a[pos][i] != son[pos]) efs(a[pos][i], pos, a[pos][i]); } int lca(int x, int y) { if (depth[x] < depth[y]) swap(x, y); for (int i = MAXLOG - 1; i >= 0; i--) if (depth[father[x][i]] >= depth[y]) x = father[x][i]; if (x == y) return x; for (int i = MAXLOG - 1; i >= 0; i--) if (father[x][i] != father[y][i]) { x = father[x][i]; y = father[y][i]; } return father[x][0]; } int ancestor(int x, int k) { if (k == 0) return x; if (k >= depth[x]) return 0; int tmp = highbit[k]; k -= 1 << tmp; x = father[x][tmp]; int delta = depth[x] - depth[up[x]] - k; if (delta >= 0) return lst[up[x]][1][delta]; else return lst[up[x]][0][-delta]; } int findnxt(int x, int d) { if (f[x][d] == x) return x; else return f[x][d] = findnxt(f[x][d], d); } void modify(int pos) { if (vis[pos] && val[pos] == 1) return; ll delta = val[pos]; vis[pos] = true; val[pos] = sqrt(val[pos]); delta = val[pos] - delta; if (val[pos] == 1) { for (int i = 1, now = father[pos][0]; i < limit; i++, now = father[now][0]) if (now) f[findnxt(pos, i)][i] = findnxt(now, i); } for (int i = 1; i < limit; i++) { BIT[i].modify(dfn[pos][i], delta); BIT[i].modify(rit[pos][i] + 1, -delta); } } void label(int pos, int fa, int k) { int now = depth[pos] % k; dfn[pos][k] = ++timer[now]; for (unsigned i = 0; i < a[pos].size(); i++) if (a[pos][i] != fa) label(a[pos][i], pos, k); rit[pos][k] = timer[now]; } int main() { read(n); for (int i = 1; i <= n; i++) read(val[i]); for (int i = 1; i <= n - 1; i++) { int x, y; read(x), read(y); a[x].push_back(y); a[y].push_back(x); } for (int i = 1; i <= n; i++) { for (int j = 1; j < limit; j++) f[i][j] = i; highbit[i] = highbit[i - 1]; if (1 << (highbit[i] + 1) == i) highbit[i]++; } dfs(1, 0); efs(1, 0, 1); for (int j = 1; j < limit; j++) { BIT[j].init(n); memset(timer, 0, sizeof(timer)); for (int i = 1; i <= n; i++) timer[depth[i] % j + 1]++; for (int i = 1; i <= j; i++) timer[i] += timer[i - 1]; label(1, 0, j); for (int i = 1; i <= n; i
相關推薦
【LOJ2322】「清華集訓 2017」Hello world!
【題目連結】 點選開啟連結 【思路要點】 一個 1
【LOJ2328】「清華集訓 2017」避難所
【題目連結】 點選開啟連結 【思路要點】 令 x
【LOJ2326】「清華集訓 2017」簡單資料結構
【題目連結】 點選開啟連結 【思路要點】 注意到答案是 O
【LOJ2323】「清華集訓 2017」小 Y 和地鐵
【題目連結】 點選開啟連結 【思路要點】 很不錯的腦洞題。 附上官方題解。 時間複雜度 O
【LOJ2324】「清華集訓 2017」小 Y 和二叉樹
【題目連結】 點選開啟連結 【思路要點】 答案的第一位一定是編號最小的度數不為 3
【LOJ2329】「清華集訓 2017」我的生命已如風中殘燭
【題目連結】 點選開啟連結 【思路要點】 一個直觀的思路是模擬該過程,當路上遇到環的時候通過類似取模的手段加速。 注意到每繞一個環
【LOJ2331】「清華集訓 2017」某位歌姬的故事
【題目連結】 點選開啟連結 【思路要點】 注意到若一個位置被兩種音高 a
【LOJ2330】「清華集訓 2017」榕樹之心
【題目連結】 點選開啟連結 【思路要點】 首先,樹是二分圖,只有一側的點可能成為心。 維護每一棵子樹會產生的向下推動的次數可能的最大值
【LOJ2327】「清華集訓 2017」福若格斯
【題目連結】 點選開啟連結 【思路要點】 M
【LOJ2320】「清華集訓 2017」生成樹計數
【題目連結】【思路要點】連上\(a_i\)的限制,題目要求的實際上是\(\sum_{T}\prod_{i=1}^{N}a_i^{d_i}*d_i^{M}\sum_{i=1}^{N}d_i^{M}\)。我們知道樹的Prufer序列與樹點的度數密切相關,因此考慮使用Prufer序
【LOJ2321】「清華集訓 2017」無限之環
【題目連結】 【思路要點】 先說這道題的正解: 將棋盤看做一張二分圖,每一條邊拆成兩個點,分別屬於二分圖的一邊。 我們需要做一件類似於匹配的事情,同一條邊的兩側或是都沒有管道,或是都有管道。 通過合適的建邊我們能夠用最小費用最大流來解決本題。 時間複雜度
【LOJ】#2320. 「清華集訓 2017」生成樹計數
rac res 然而 除了 加法 wap OS 代碼 reg 題解 我,理解題解,用了一天 我,卡常數,又用了一天 到了最後,我才發現,我有個加法取模,寫的是while(c >= MOD) c -= MOD 我把while改成if,時間,少了 六倍。 六倍。 六倍!!
loj#2330. 「清華集訓 2017」榕樹之心【樹形dp】
傳送門 解題思路: 先考慮根是否可行,即步數是否能抵消完。 考慮w[x]w[x]表示xx的子樹內最少的消剩下的點數。 觀察發現,最難消的肯定是sizesize最大的兒子,設為 yy ,而且如果
【LOJ】#2330. 「清華集訓 2017」榕樹之心 -樹形dp
題解 先考慮根的情況(Subtask3Subtask3)。 根的每個兒子及其構成的子樹之間可以互相抵消。 設rem[i]rem[i]表示以ii為根的子樹最少的不能互相抵消的點數。 那
「清華集訓 2017」無限之環
無限之WA https://www.luogu.org/problemnew/show/P4003 本題如果知道是網路流的話,其實建圖不算特別神奇,但是比較麻煩。 資料範圍過大,插頭dp不能處理,而且是一個網格圖,考慮網路流。 先看是不是二分圖? 每個格子只會和相鄰四個格子發生關係 所以,黑白染色
LOJ2325「清華集訓 2017」小Y和恐怖的奴隸主(期望概率+矩陣快速冪)
LOJ2325「清華集訓 2017」小Y和恐怖的奴隸主 題意: "A fight? Count me in!" 要打架了,算我一個。 "Everyone, get in here!" 所有人,都過來! 小Y是一個喜歡玩遊戲的OIer。一天,她正在
LOJ2321「清華集訓 2017」無限之環
無限之環 題目描述 曾經有一款流行的遊戲,叫做InfinityLoopInfinityLoop,先來簡單的介紹一下這個遊戲: 遊戲在一個 n×mn×m的網格狀棋盤上進行,其中有些小方格中會有水管,水管可能在方格某些方向的邊界的中點有介面,所
「清華集訓2017」榕樹之心
name clear 方向 世界 oid 可行性 pre lin size 「清華集訓2017」榕樹之心 “已經快是嚴冬了,榕樹的葉子還沒落呢……” “榕樹是常綠樹,是看不到明顯的落葉季節的……” “唉……想不到已經七年了呢。榕樹還是當年的榕樹,你卻不是當年的你了……”
【期望+矩陣乘法】LOJ2325 [清華集訓 2017] 小 Y 和恐怖的奴隸主
【題目】 原題地址 BOSS \text{BOSS} BOSS初始有一個
UOJ #36「清華集訓2014」瑪裡苟斯
這怎麼想得到啊......... UOJ #36 題意:求隨機一個集合的子集的異或和的$k$次方的期望值,保證答案$ \lt 2^{63},1 \leq k \leq 5$ $ Solution:$ 首先考慮$ k=1$的時候怎麼做:如果某位上有$ 1$則有$ \frac{1}{2}$的