樹鏈剖分 p1505 國家集訓隊 旅遊

2022-05-27 17:15:20 字數 3065 閱讀 9405

ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說, t 城中只有n − 1 座橋。

ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹窄泥濘,令人煩躁。於是,他給每座橋定義乙個愉悅度w,也就是說,ray 經過這座橋會增加w 的愉悅度,這或許是正的也可能是負的。有時,ray 看待同一座橋的心情也會發生改變。

現在,ray 想讓你幫他計算從u 景點到v 景點能獲得的總愉悅度。有時,他還想知道某段路上最美麗的橋所提供的最大愉悅度,或是某段路上最糟糕的一座橋提供的最低愉悅度。

輸入的第一行包含乙個整數n,表示t 城中的景點個數。景點編號為 0...n − 1。

接下來n − 1 行,每行三個整數u、v 和w,表示有一條u 到v,使 ray 愉悅度增加w 的橋。橋的編號為1...n − 1。|w| <= 1000。 輸入的第n + 1 行包含乙個整數m,表示ray 的運算元目。

接下來有m 行,每行描述了乙個操作,操作有如下五種形式:

測試資料保證,任意時刻,ray 對於經過每一座橋的愉悅度的絕對值小於等於1000。

對於每乙個詢問(操作s、max 和min),輸出答案。

樹剖裸題,邊權轉點權,直接賦給深度較深的點.

查詢的時候由於會出多修改乙個點的問題,所以要\(+1\)。

這裡把編號從\(0\)到\(n-1\)變成了\(1\)到\(n\).

貌似這樣會少很多鍋?單點修改也要下放標記。怪不得一直wa

**

#include#include#include#include#define int long long

#define ls o<<1

#define rs o<<1|1

#define n 1000080

#define r register

using namespace std;

inline void in(int &x)

while(isdigit(s))

x*=f;

}int n,head[n],tot,depth[n],size[n],f[n],son[n],val[n];

struct codedge[n<<1];

int tr[n<<2],mn[n<<2],mx[n<<2],m,tg[n<<2];

int dfn[n],fdfn[n],idx,top[n];

char s[8];

inline void add(int x,int y,int z)

inline void up(int o)

inline void down(int o,int l,int r)

}void build(int o,int l,int r)

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

build(ls,l,mid);

build(rs,mid+1,r);

up(o);

}void change(int o,int l,int r,int pos,int w)

down(o,l,r);

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

if(pos<=mid)change(ls,l,mid,pos,w);

else change(rs,mid+1,r,pos,w);

up(o);

}void qufan(int o,int l,int r,int x,int y)

down(o,l,r);

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

if(x<=mid)qufan(ls,l,mid,x,y);

if(y>mid)qufan(rs,mid+1,r,x,y);

up(o);

}int query_sum(int o,int l,int r,int x,int y)

int query_max(int o,int l,int r,int x,int y)

int query_min(int o,int l,int r,int x,int y)

void dfs1(int u,int fa,int dis)

else

fx=top[x],fy=top[y];

} if(x == y) return ;

if(dfn[x]>dfn[y])swap(x,y);

qufan(1,1,idx,dfn[x]+1,dfn[y]);

}inline int tquery(int x,int y)

else

fx=top[x],fy=top[y];

} if(x == y) return res ;

if(dfn[x]>dfn[y])swap(x,y);

res+=query_sum(1,1,idx,dfn[x]+1,dfn[y]);

return res;

}inline int tquery_min(int x,int y)

else

fx=top[x],fy=top[y];

} if(x == y) return res ;

if(dfn[x]>dfn[y])swap(x,y);

res=min(res,query_min(1,1,idx,dfn[x]+1,dfn[y]));

return res;

}inline int tquery_max(int x,int y)

else

fx=top[x],fy=top[y];

} if(x == y) return res ;

if(dfn[x]>dfn[y])swap(x,y);

res=max(res,query_max(1,1,idx,dfn[x]+1,dfn[y]));

return res;

}signed main()

else if(s[0]=='n')

else if(s[0]=='s')

else if(s[1]=='a')

else if(s[1]=='i')

}}

P1505 國家集訓隊 旅遊 樹鏈剖分

題目描述 ray 樂忠於旅遊,這次他來到了t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有...

P1505 國家集訓隊 旅遊 (樹鏈剖分)

傳送門 很明顯是樹鏈剖分,因為是邊權,所以將每個邊權給深度大的那個點可以了,根節點不用賦值,要求最大值和最小值,所以線段樹不包含根節點。因為點是從0編號的,所以父節點和重兒子陣列要初始化。include include include using namespace std const int n ...

P1505 國家集訓隊 旅遊

題目鏈結 這道題其實還是比較好想的,同樣是邊權問題。我們需要維護最大值,最小值,和。最坑的地方就是路徑上的所有數變相反數,其實這個就是把區間和 1,區間最大 1,區間最小 1,最後pushdown的時候將取反標記 1,接下來一系列都是常規操作。而這裡還要記住,單點修改時也要下傳lazy標記。而我在跳...