HDOJ5692解題報告 dfs序 線段樹

2022-03-01 10:18:44 字數 2995 閱讀 2919

題目概述:

中文題面就不贅述了。

大致思路:

這個題給出的是一棵樹,我們可以使用dfs序將這棵樹處理成一條鏈,然後對這條鏈來進行資訊維護和查詢。

有兩種操作,0 x是詢問從0出發(題目保證0為樹根)經過x的路徑中的最大權值,1 x y是將點x的權值修改成y,這時我們用線段樹來維護乙個d[i]表示點i到0點的權值和。

對於第一種操作就是查詢x及其子樹上的最大值,經過dfs序的處理之後這是一段連續的區間,求乙個最大值即可。

對於第二種操作我們只需要在x及其子樹上add乙個y-a[x]即可。

注意可能爆棧,記得按題目裡的提示處理。

複雜度分析:

dfs序是o(n),線段樹查詢跟區間修改是o(logn),建樹o(nlogn),綜上o(nlogn*t)

**:

#pragma comment(linker, "/stack:1024000000,1024000000")#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define sacnf scanf

#define scnaf scanf

#define maxn 100010

#define maxm 18

//#define inf 1061109567

const

long

long inf=1e15;

#define inf 0x3f3f3f3f

#define eps 0.000001

const

double pi=acos(-1.0

);#define mod 1000000007

#define maxnum 10000

#define for(i,j,k) for(int (i)=(j);(i)<=(k);(i)++)

#define mes(a,b) memset((a),(b),sizeof(a))

#define scanfi(a) scanf("%d",&(a))typedef

long

long

ll;typedef unsigned

long

long

ulld;

void swap(int &a,int &b)

ll abs(ll x)

struct

node

tree[maxn*3

];vector

g[maxn];

intdfs_clock,pre[maxn],low[maxn],turn[maxn];

ll d[maxn],a[maxn];

void dfs(int

u,ll sum)

low[u]=dfs_clock;d[pre[u]]=sum+a[u];

turn[u]=pre[u];

}void build_tree(int l,int r,int

dir)

int m=(l+r)>>1

; build_tree(l,m,dir*2

); build_tree(m+1,r,dir*2+1

); tree[dir].add=0

; tree[dir].max=max(tree[dir*2].max,tree[dir*2+1

].max);

}void add_in(int

dir,ll val)

void push_down(int

dir)

}void maintain(int

dir)

void add(int l,int r,int dir,int al,int

ar,ll val)

push_down(dir);

int m=(l+r)>>1

;

if(al<=m) add(l,m,dir*2

,al,ar,val);

if(ar>m) add(m+1,r,dir*2+1

,al,ar,val);

maintain(dir);

}ll ans;

void query(int l,int r,int dir,int ql,int

qr) push_down(dir);

int m=(l+r)>>1

;

if(ql<=m) query(l,m,dir*2

,ql,qr);

if(qr>m) query(m+1,r,dir*2+1

,ql,qr);

maintain(dir);

}int

main()

for(i,

1,n-1

)

for(i,

1,n) scanf("

%lld

",&a[i]);

dfs(

1,0);build_tree(1,n,1

);

//coutopt,x;ll y;

while(m--)

else

if(opt==1

) }}

//clock_t ed=clock();

//printf("\n\ntime used : %.5lf ms.\n",(double)(ed-st)/clocks_per_sec);

return0;

}

HDOJ3639解題報告 縮點 dfs

題目概述 題面有點翻譯不來 可以用chrome自帶的那個翻譯。大致思路 如果跑bfs或者dfs遇到環的話就會出問題,所以先跑一遍tarjan求強連通分量,把環的情況去掉,在剩下的圖上做。這個時候發現樣例1裡2這個節點指向的兩個節點都是答案,所以反向建圖,用dfs求出所有入度為0的點的子樹大小,最大數...

hdoj1181解題報告,DFS,標記用過的的方法

給一堆字串,判斷能否從某個字母做開頭,首尾相連,到某個字母的結尾 要注意,每一種變換只能使用一次,例如b t,只能用一次。否則無限迴圈。include include includeusing namespace std char s 2000 int m 30 30 vis 30 30 int x...

HDOJ4366解題報告 dfs序 線段樹

題目概述 給出乙個公司所有員工的上下級關係 資料保證是一棵樹 現在想解雇一些員工,而他們的位置由他們的手下裡能力值比他大而且忠誠度最高的人來替代,給出m個詢問,求輸出替代他們的人的編號。大致思路 學習了一下dfs序的用法,附學習的部落格 簡單的說dfs序就是將一棵樹變成線性結構的演算法,並且保證點i...