problem 旅行 (bzoj 3531)
題目大意
給定一顆樹,樹上的每個點有兩個權值(x,y)。
要求維護4種操作:
操作1:更改某個點的權值x。
操作2:更改某個點的權值y。
操作3:求a-->b路徑上所有x屬性與a,b相同的點y屬性的和。
操作4:求a-->b路徑上所有x屬性與a,b相同的點y屬性的最大值。
n,q ,x <= 10^5 , y <= 10^4
解題分析
由於x屬性的範圍較大,無法直接統計。
考慮每次修改為單點修改,詢問時只對相同x屬性的詢問。
因此,對於每個x屬性開一棵線段樹,詢問時直接在相對應的線段樹內查詢。
開這麼多棵線段樹的話,就要動態開點,某個點的左右兒子的編號不是當前點編號的2倍或2倍加1。
參考程式
1 #include 2 #include 3 #include 4 #include 5view codeusing
namespace
std;67
#define n 10000008
8#define v 100008
9#define e 200008
10#define lson l,m,ls[rt]
11#define rson m+1,r,rs[rt]
1213
intn,q,cnt;
14int
size[v],dep[v],fa[v],son[v],w[v],top[v],rk[v],root[v];
15int
a[v],c[v];
1617
struct
lineeg[e];
20int
lt[v],sum;
2122
void adt(int u,int
v)25
void add(int u,int
v)28
29struct
segment_tree
35void update(int x,int val,int l,int r,int &rt)
42int m=(l+r)/2;43
if (x <=m) update(x,val,lson);
44if (m
45pushup(rt);46}
47int query_sum(int l,int r,int l,int r,int
rt)51
int m=(l+r)/2;52
int res=0;53
if (l <= m) res+=query_sum(l,r,lson);
54if (m < r) res+=query_sum(l,r,rson);
55return
res; 56}
57int query_max(int l,int r,int l,int r,int
rt)61
int m=(l+r)/2;62
int res=0;63
if (l <= m) res=max(res,query_max(l,r,lson));
64if (m < r) res=max(res,query_max(l,r,rson));
65return
res; 66}
67}t;
6869
void dfs_1(int
u)79}80
void dfs_2(int u,int
tp) 88}
89void solve_sum(int x,int
y)96
if (dep[x]>dep[y]) swap(x,y);
97 res+=t.query_sum(w[x],w[y],1
,n,root[cl]);
98 printf("
%d\n
",res);99}
100void solve_max(int x,int
y)107
if (dep[x]>dep[y]) swap(x,y);
108 res=max(res,t.query_max(w[x],w[y],1
,n,root[cl]));
109 printf("
%d\n
",res);
110}
111112
intmain()
121 dfs_1(1
);122 dfs_2(1,1
);123 cnt=0
;124
for (int i=1;i<=n;i++) t.update(w[i],a[i],1
,n,root[c[i]]);
125while (q--)
134if (strcmp(x,"
cw")==0
)138
if (strcmp(x,"
qs")==0
)141
if (strcmp(x,"
qm")==0
)144
}145 }
bzoj3531 樹刨 線段樹動態開點
題意 一棵樹,每個點有顏色,4種操作,1.單點修改權值 2.單點修改顏色 3.查詢路徑顏色相同的點權和 4.查詢路徑顏色相同的點權最大值。思路 樹刨 線段樹動態開點,開1e5個線段樹。include using namespace std define ll long long define for...
BZOJ 2243 樹鏈剖分 線段樹
include define n 101000 define frei freopen in.txt r stdin define freo freopen out.txt w stdout define mem a,b memset a,b,sizeof a define lson root 1 ...
BZOJ 4811 樹鏈剖分 線段樹
思路 感覺這題也可神了.還是我太弱 首先發現每一位不會互相影響,可以把每一位分開考慮,然後用樹鏈剖分或者lct維護這個樹 修改直接修改,詢問的時候算出來每一位填0,1經過這條鏈的變換之後得到的值 考慮貪心,從高往低,如果這一位填0可以得到1,那麼填0一定是最優的 否則如果可以填1,就把這一位填為1 ...