P4069 SDOI2016 遊戲 樹剖 李超樹

2022-06-13 21:00:12 字數 1580 閱讀 7848

戳這裡

首先樹上路徑操作,要用樹剖

其次,操作等價於區間加一條線段,然後查詢區間最小值

但是與普通李超樹不同,這次 \(x\) 值並不連續,每次插入的線段下標是和給定起點的距離,那麼我們更改一下維護的資訊,線段樹上 \(a\) 點的 $x $ 值是它離根的距離,然後我們將操作轉化,每次插入的線段分成兩條

\(s\to lca\)

這一部分距離隨編號減小而增大,所以斜率由 \(k\) 變為 \(-k\),\(b\) 的初值就是 \(dis[s]*k+b\)

\(lca\to t\)

這一部分距離隨編號增大而增大,,那麼斜率不變, \(b\) 值變為 \((dis[s]-(dis[lca]*2)*k+b)\)

之後就是維護區間最小值,但注意由於標記永久化的操作,我們需要每一次將答案和對應區間內 \(max(l,ql)\) ~ \(min(r,qr)\) 的部分的最小值取 \(min\)

#include#define lc (rt<<1)

#define rc (rt<<1)|1

using namespace std;

namespace zzc

while(isdigit(ch))

return x*f; }

const int maxn = 1e5+5;

long long n,m,cnt,idx;

long long head[maxn],siz[maxn],fa[maxn],son[maxn],top[maxn],dep[maxn],dfn[maxn],dis[maxn],id[maxn];

struct edge

e[maxn<<1];

void add(int u,int v,int w)

struct line

long long calc(long long pos)

};struct node

node(){}

}t[maxn<<2];

void dfs1(int u,int ff) }

void dfs2(int u,int bel) }

void pushup(int rt)

void build(int rt,int l,int r)

int lca(int x,int y)

void update(int rt,int l,int r,int ql,int qr,line x)

long long query(int rt,int l,int r,int ql,int qr)

void update_tree(int u,int v,long long k,long long b)

update(1,1,n,dfn[v],dfn[u],x); }

long long query_tree(int s,int t)

void work()

dfs1(1,0);dfs2(1,1);

build(1,1,n);

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

else

} }

}int main()

SDOI2016 硬幣遊戲

題目 翻硬幣遊戲啊 首先對於這類遊戲只要滿足如下的規則,就可以用一種特殊的方式解決了 我們假定只能翻正面朝上的硬幣 我們可以根據某些約束條件的翻硬幣 一次反掉連續幾個,或者具有某些特殊性質的 但是翻掉的硬幣中最右邊的那個比如是從正面反到反面 誰不能翻硬幣了誰輸 對於滿足這樣的特徵的硬幣遊戲,我們有這...

SDOI2016 遊戲題解

這道題太噁心了,調了我整整一晚上,結果發現是乙個bi 錯誤,多多捂臉 這道題比之前的題多了乙個初始化和區間查詢的操作,主要是區間查詢噁心 因為要區間查詢,所以必須維護區間最低點,修改和查詢操作被改得面目全非。我們要維護的話,必須從現值,子值,新值,具體的不好多說 看 吧 include define...

洛谷 SDOI2016 遊戲

初見安 這裡是傳送門 洛谷p4069 sdoi2016 遊戲 這題真的是咕了好幾個月了終於過了,然後又咕了幾個星期才來寫部落格 題意很簡單,每次讓你在一條路徑上放乙個等差數列,問你某點上數的最小值。這就是乙個李超線段樹的模板題了。我們樹上利用樹剖開一棵線段樹,維護每一段等差序列的最小值就好。接下來看...