樹鏈剖分,先求出每個點的dfs序區間,查詢時假設當前根為x,查詢點為y,他們的dfs序分別為[xl,xr],[yl,yr],有三種情況,第一種x=y那麼直接輸出[1,n]的最小值,第二種這兩個區間分離或者[xl,xr]包含[yl,yr],那麼直接查詢[yl,yr]的最小值,第三種[yl,yr]包含[xl,xr],找到x到y的路徑上離y最近的點z,其區間為[zl,zr],那麼需要輸出min([1,zl-1],[zr+1,n])。
**
1 #include2 #include3#define n 2000010
4using
namespace
std;
5 typedef long
long
ll;6
intdp,pre[n],p[n],tt[n],f[n],gf[n],go[n];
7int
l[n],r[n],tot,n,m,i,deep[n];
8int
l[n],r[n],a,b,root,typ;
9int jump[110000][19
];10
ll value[n],e[n],c,v[n],s[n],inf;
11void link(int x,int
y)12
15void dfs1(int x,int
fa)16
29 i=pre[i];30}
31}32void dfs2(int x,int fa,int
fa)33
43 r[x]=tot;44}
45void build(int x,int a,int
b)46
55else
56 s[x]=e[b];57}
58void clean(int
x)5967}
68void change(int x,int a,int
b,ll c)
6976
int m=(l[x]+r[x])>>1;77
if (a2*x,a,b,c);
78if (m2*x+1
,a,b,c);
79 clean(2*x);clean(2*x+1
);80 s[x]=min(s[2*x],s[2*x+1
]);81
}82 ll query(int x,int a,int
b)83
94void gao(int a,int
b,ll c)
95104
else
105110
}111
}112
int find(int x,int
y)113
119int
main()
120128
for (i=1;i<=n;i++)
129 scanf("
%lld
",&value[i]);
130 dfs1(1,0
);131 dfs2(1,1,0
);132 build(1,0
,n);
133 scanf("
%d",&root);
134for (i=1;i<=m;i++)
135144
else
145158
else
159 printf("
%lld\n
",query(1,l[a]-1
,r[a]));
160}
161}
162 }
bzoj3083 遙遠的國度
題意 給定一棵樹,支援換根,路徑權值覆蓋,求子樹最小。思路 求子樹?上樹鏈剖分,但是換根怎麼辦?我們只能通過原有資訊推出換根後的答案。換根不影響路徑修改,所以只要考慮子樹最小值的維護。這裡要分3種情況討論 1 如果詢問點是當前根,直接返回整棵樹的最小值。2 如果在原樹中,當前根不在 x的子樹中,直接...
bzoj3083 遙遠的國度
time limit 10 sec memory limit 1280 mb submit 1733 solved 429 submit status discuss description 描述 zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的...
bzoj3083 遙遠的國度
time limit 10 sec memory limit 1280 mb submit 1960 solved 484 submit status discuss 描述zcwwzdjn在追殺十分sb的zhx,而zhx逃入了乙個遙遠的國度。當zcwwzdjn準備進入遙遠的國度繼續追殺時,守護神ra...