BZOJ 3306 树
2016-08-26 12:09
267 查看
dfs序建线段树+分类讨论+写的有点长。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100500 #define maxe 200500 #define inf 2147483646 using namespace std; int n,m,w[maxv],dfn[maxv],fdfn[maxv],g[maxv],nume=0,x,y,cnt=0,dis[maxv],mx[maxv],anc[maxv][23]; int tot=0,root,ls[maxv<<2],rs[maxv<<2],val[maxv<<2],nrt; char s[4]; struct edge { int v,nxt; }e[maxe]; void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs(int x,int fath) { dfn[x]=++cnt;mx[x]=dfn[x];fdfn[cnt]=x; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v==fath) continue; dis[v]=dis[x]+1; dfs(v,x);anc[v][0]=x; mx[x]=max(mx[x],mx[v]); } } void get_table() { for (int e=1;e<=20;e++) for (int i=1;i<=n;i++) anc[i][e]=anc[anc[i][e-1]][e-1]; } void build(int &now,int left,int right) { now=++tot; if (left==right) { val[now]=w[fdfn[left]]; return; } int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); val[now]=min(val[ls[now]],val[rs[now]]); } void modify(int now,int left,int right,int pos) { if ((left==right) && (left==pos)) { val[now]=w[fdfn[left]]; return; } int mid=(left+right)>>1; if (pos<=mid) modify(ls[now],left,mid,pos); else modify(rs[now],mid+1,right,pos); val[now]=min(val[ls[now]],val[rs[now]]); } int ask(int now,int left,int right,int l,int r) { if (l>r) return inf; if ((l<=0) || (r>=n+1)) return inf; if ((left==l) && (right==r)) return val[now]; int mid=(left+right)>>1; if (r<=mid) return ask(ls[now],left,mid,l,r); else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r); else return min(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+1,right,mid+1,r)); } int find(int x,int pos) { for (int e=20;e>=0;e--) { if (dis[anc[x][e]]>dis[pos]) x=anc[x][e]; } return x; } int main() { freopen("cin.in","r",stdin); freopen("a.out","w",stdout); nrt=1; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { scanf("%d%d",&x,&w[i]); if (x!=0) {addedge(i,x);addedge(x,i);} } dfs(1,1); get_table(); build(root,1,n); for (int i=1;i<=m;i++) { scanf("%s",s); if (s[0]=='V') { scanf("%d%d",&x,&y); w[x]=y; modify(root,1,n,dfn[x]); } else if (s[0]=='E') scanf("%d",&nrt); else { scanf("%d",&x); if (x==nrt) printf("%d\n",val[1]); else if ((dfn[nrt]>=dfn[x]) && (dfn[nrt]<=mx[x])) { int r=find(nrt,x); printf("%d\n",min(ask(root,1,n,1,dfn[r]-1),ask(root,1,n,mx[r]+1,n))); } else printf("%d\n",ask(root,1,n,dfn[x],mx[x])); } } return 0; }
相关文章推荐
- [BZOJ3306]树
- 【BZOJ3083/3306】遥远的国度/树 树链剖分+线段树
- BZOJ 3306: 树
- 【bzoj3306】树
- bzoj 3306
- 【bzoj3306】【树】【dfs序+线段树】
- BZOJ 3306 树 Link-Cut-Tree+set
- 【bzoj3306】树
- 【bzoj 3306】树
- [BZOJ3306]树(dfs序)
- 【bzoj3306】树
- bzoj3306 树
- 【BZOJ-3306】树 线段树 + DFS序
- 【BZOJ 3306】树【LCA、DFS序、线段树】
- BZOJ 3306|树|树链剖分
- bzoj 3306: 树 dfs序+线段树
- bzoj3083 3306
- bzoj3306: 树(dfs序+倍增+线段树)
- [bzoj3306]树——树上倍增+dfs序+线段树
- [bzoj3306]树 dfs序+线段树