bzoj 1036 樹的統計Count

2022-06-01 07:03:11 字數 3820 閱讀 5006

題目大意:

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w

我們將以下面的形式來要求你對這棵樹完成一些操作:

i. change u t : 把結點u的權值改為t

ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值

iii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 注意:從點u到點v的路徑上的節點包括u和v本身

思路:樹鏈剖分

衣服都不穿的

搞到線段樹里,然後維護維護

背一背**

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

#define inf 2139062143

10#define ll long long

11#define maxn 30101

12#define mod

13using

namespace

std;

14 inline int

read()

1518

while(isdigit(ch))

19return x*f;20}

21int n,cnt,nxt[maxn*2],fst[maxn],to[maxn*2

],val[maxn];

22int

fa[maxn],dep[maxn],bl[maxn],cnt[maxn],hsh[maxn];

23struct datatr[maxn*3

];24

void add(int u,int v)

25void build(int

x)26

35 cnt[x]++;36}

37void build(int x,int

chn)

3847

void s_build(int k,int l,int

r)48

55void upd(int k,int pos,int

x)56

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

if(mid>=pos) upd(k<<1

,pos,x);

61else upd(k<<1|1

,pos,x);

62 tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1

].mx);

63 tr[k].sum=tr[k<<1].sum+tr[k<<1|1

].sum;64}

65int q_sum(int k,int a,int

b)66

74int q_mx(int k,int a,int

b)75

83int

main()

8487

for(int i=1;i<=n;i++) val[i]=read();fa[1]=1

;88 build(1);cnt=0

;89 build(1,1

);90 s_build(1,1

,n);

91for(int i=1;i<=n;i++) upd(1

,hsh[i],val[i]);

92int t=read();

93char ch[8

];94

while(t--)

9598

else

if(ch[1]=='m'

)99107 res=max(res,q_mx(1

,min(hsh[a],hsh[b]),max(hsh[a],hsh[b])));

108 printf("

%d\n

",res);

109}

110else

if(ch[1]=='s'

)111

119 res+=q_sum(1

,min(hsh[a],hsh[b]),max(hsh[a],hsh[b]));

120 printf("

%d\n

",res);

121}

122}

123 }

view code

upd 2018.9.19

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include12

#define ll long long

13#define inf 2147383611

14#define maxn 500100

15using

namespace

std;

16 inline int

read()

1721

while(isdigit(ch))

22return x*f;23}

24int n,cnt,nxt[maxn<<1],fst[maxn],to[maxn<<1

],val[maxn];

25int fa[maxn],dep[maxn],bl[maxn],sz[maxn],hsh[maxn],mx[maxn<<2],sum[maxn<<2

];26

void add(int u,int v)

27void dfs(int

x)2832}

33void dfs(int x,int

anc)

3441}42

void mdf(int k,int l,int r,int x,int

w)43

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

if(x<=mid) mdf(k<<1

,l,mid,x,w);

47else mdf(k<<1|1,mid+1

,r,x,w);

48 mx[k]=max(mx[k<<1],mx[k<<1|1]),sum[k]=sum[k<<1]+sum[k<<1|1

];49}50

int querys(int k,int l,int r,int a,int

b)51

58int querym(int k,int l,int r,int a,int

b)59

66int

main()

6770 dfs(1);cnt=0;dfs(1,1

);71

for(int i=1;i<=n;i++) mdf(1,1

,n,hsh[i],read());

72 t=read();

73while(t--)

7486 res=max(res,querym(1,1

,n,min(hsh[a],hsh[b]),max(hsh[a],hsh[b])));

87 printf("

%d\n

",res);88}

89else

if(ch[1]=='s'

)9098 res+=querys(1,1

,n,min(hsh[a],hsh[b]),max(hsh[a],hsh[b]));

99 printf("

%d\n

",res);

100}

101}

102 }

view code

bzoj1036 樹的統計

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...

Bzoj1036 樹的統計

一棵 樹上有n 個節點,編號分別 為1到n 每個節 點都有一 個權值w 我們將 以下面的 形式來要 求你對棵 樹完成一 些操作 1.把結 點u的權 值改為t 2.詢問 從點u到 點v的路 徑上的節 點的最大 權值3.詢問 從點u到 點v的路 徑上的節 點的權值 和 注意 從點u 到點v的 路徑上的 ...

bzoj 1036 樹的統計

description 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的...