luogu P3787 冰精凍西瓜

2022-05-09 13:24:11 字數 2669 閱讀 4367

嘟嘟嘟

好題,好題……

看這個修改和詢問,就知道要麼是求完dfs序後線段樹維護,要麼是樹剖。又因為這道題都是子樹的操作,沒有鏈上的,所以線段樹就夠了。

然而重點不是這個。這道題最麻煩的是線段樹pushdown時對於每乙個節點打的標記都不一樣,因為每一條邊上的能力值不一樣。這也是這道題最巧妙的一點:我們把每一次對節點 i 放的冷氣都轉移到從根節點放的,這樣pushdown的標記就統一了。

具體操作是啥咧:假如u到跟要經過w1, w2, w3這三條邊,那麼我們對u放x的冷氣,就相當於從根節點放div[u] = w1 * w2 * w3  * x的冷氣,查詢v的冷氣值的時候把線段樹得到的答案除以div[v]即可。預處理div[i]dfs一遍即可。

然而這道題還沒完,因為div[i]可以等於0,所以這棵樹實際上會斷成乙個森林。所以就有好多個根節點,以及好多棵線段樹,但是空間大小是不變的。

所以要記錄每一棵樹的根節點,再從根節點開始dfs,維護的div[i]實際上表示的是 i 到他所在的樹的根節點的πwi。(一定是從根節點開始!我就是因為從樹中任意一棵節點開始導致85分,今天聽bin哥講完後突然才想出來這個問題)

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11

using

namespace

std;

12#define enter puts("")

13#define space putchar(' ')

14#define mem(a, x) memset(a, x, sizeof(a))

15#define rg register

16 typedef long

long

ll;17 typedef double

db;18

const

int inf = 0x3f3f3f3f;19

const db eps = 1e-9;20

const

int maxn = 1e5 + 5;21

inline ll read()

2226

while(isdigit(ch))

27if(last == '

-') ans = -ans;

28return

ans;29}

30 inline void

write(ll x)

3136

37int

n, m;

38struct

edge

39e[maxn << 1

];43

int head[maxn], ecnt = -1;44

void addedge(int x, int

y, db w)45;

47 head[x] =ecnt;48}

4950

int st[maxn], top = 0;51

bool

vis[maxn];

52int

rt[maxn], bel[maxn];

53int siz[maxn], dfsx[maxn], pos[maxn], cnt = 0;54

db div[maxn];

55bool

zero(db x)

5659

void dfs(int now, int

id)6073}

74}7576

int ls[maxn << 2], rs[maxn << 2], ctr = 0

;77 db sum[maxn << 2], lzy[maxn << 2

];78

void pushdown(int

now)

7988}89

void update(int l, int r, int l, int r, int&now, db d)

9093

pushdown(now);

94int mid = (l + r) >> 1;95

if(r <=mid) update(l, mid, l, r, ls[now], d);

96else

if(l > mid) update(mid + 1

, r, l, r, rs[now], d);

97else update(l, mid, l, mid, ls[now], d), update(mid + 1, r, mid + 1

, r, rs[now], d);98}

99 db query(int l, int r, int& now, int

id)100

108109

intmain()

110119 div[1] = 1.00; dfs(1, 1

);120

for(int i = 1; i <= top; ++i) div[st[i]] = 1.00

, dfs(st[i], st[i]);

121 m =read();

122for(int i = 1; i <= m; ++i)

123131

else

132136

}137

return0;

138 }

view code

bzoj3787 Gty的文藝妹子序列

我們回憶bzoj3289的做法,可以使用莫隊演算法,加上線段樹進行茲瓷in,out,query。我們回憶經典分塊做法。預處理ans i,j 表示第i塊到第j塊的答案,sum i,j 表示前i塊元素j的個數,然後只需要再弄個樹狀陣列就可以搞了。現在我們要茲瓷修改,那我們照著原來的思路改一下。ans i...

BZOJ3787 Gty的文藝妹子序列

將序列分成 sqrt 塊,預處理出每兩塊之間的逆序對數,以及ap i 表示前i塊內數字出現次數的樹狀陣列 預處理 o n sqrt log n 修改時,ap i 可以在 o sqrt log n 複雜度內完成修改,然後考慮修改的位置對答案的貢獻,可以發現相當於某一行 某一列都加上乙個數,對於行列各開...

冰精凍西瓜 P3787洛谷

琪露諾是擁有操縱冷氣程度的能力的妖精,一天她發現了一片西瓜地。這裡有n個西瓜,由n 1条西瓜蔓連線,形成乙個有根樹,琪露諾想要把它們冷凍起來慢慢吃。這些西瓜蔓具有神奇的性質,可以將經過它的冷氣的寒冷程度放大或縮小,每條西瓜蔓放大 縮小冷氣寒冷程度的能力值為wi,表示冷氣經過它後,寒冷程度值x會變為x...