BZOJ3083: 遥远的国度
来源:互联网 发布:jsp编程技术 编辑:程序博客网 时间:2024/05/03 14:58
裸的树剖 换根之后对于一个询问只需要判断当前根是否是在原树中被该节点包含就好了
人蠢代码长 没办法
#include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>using namespace std;char c;inline void read(long long &a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}long long Heavy_Chain_Begin[100001],Heavy_Chain_Data[100001],Heavy_Chain_Place[100001],Heavy_Chain_End[100001];long long Heavy_Son[100001],Con_Son[100001];bool done[1000001];long long deep[10000001];struct Chain{Chain* next;long long data;long long other;Chain(){next=NULL;}}*Son[100001],*head[100001];const long long INF=1ll<<61;struct Segement{long long l,r;long long data;long long flag;}Segement_Tree[1000001];void Build_Segement_Tree(long long place,long long l,long long r){ Segement_Tree[place].l=l; Segement_Tree[place].r=r; Segement_Tree[place].flag=false; if(l==r) { Segement_Tree[place].flag=true; Segement_Tree[place].data=Heavy_Chain_Data[l];return ; }Build_Segement_Tree(place<<1,l,(l+r)>>1);Build_Segement_Tree(place<<1|1,((l+r)>>1)+1,r);Segement_Tree[place].data=min(Segement_Tree[place<<1].data,Segement_Tree[place<<1|1].data);}inline void Pushdown(long long place){ Segement_Tree[place<<1].flag=Segement_Tree[place<<1|1].flag=true; Segement_Tree[place<<1].data=Segement_Tree[place<<1|1].data=Segement_Tree[place].data;Segement_Tree[place].flag=false;} void Segement_Change(long long place,long long l,long long r,long long data){if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r) {Segement_Tree[place].flag=true;Segement_Tree[place].data=data;return ;}if(Segement_Tree[place].flag) Pushdown(place);if(Segement_Tree[place<<1].r>=l) Segement_Change(place<<1,l,r,data);if(Segement_Tree[place<<1|1].l<=r) Segement_Change(place<<1|1,l,r,data);Segement_Tree[place].data=min(Segement_Tree[place<<1].data,Segement_Tree[place<<1|1].data);}long long Segement_Query(long long place,long long l,long long r){long long data;if(l>r) return INF;if(Segement_Tree[place].flag) return Segement_Tree[place].data;if(l<=Segement_Tree[place].l&&r>=Segement_Tree[place].r) return Segement_Tree[place].data; data=INF;if(Segement_Tree[place<<1].r>=l) data=min(data,Segement_Query(place<<1,l,r));if(Segement_Tree[place<<1|1].l<=r) data=min(data,Segement_Query(place<<1|1,l,r));return data;}long long f[1000001];void dfs(long long u){done[u]=true;Heavy_Son[u]=0;Con_Son[u]++;Chain *j,*tp;for(j=head[u];j;j=j->next) if(!done[j->other]) { tp=new Chain;tp->next=Son[u];tp->other=j->other;Son[u]=tp; deep[j->other]=deep[u]+1; f[j->other]=u;dfs(j->other); Con_Son[u]+=Con_Son[j->other]; if(Con_Son[j->other]>Con_Son[Heavy_Son[u]])Heavy_Son[u]=j->other; }}long long Heavy_Con;long long Data[1000001];long long Heavy_Chain_Node[1000001];long long root,C_root;void dfs2(long long u,long long j){Heavy_Chain_Begin[u]=j;Heavy_Chain_Place[u]=++Heavy_Con;Heavy_Chain_Data[Heavy_Con]=Data[u];Heavy_Chain_Node[Heavy_Con]=u;if(!Heavy_Son[u]) goto end; dfs2(Heavy_Son[u],j);for(Chain *tp=Son[u];tp;tp=tp->next) if(tp->other!=Heavy_Son[u]) dfs2(tp->other,Heavy_Con+1);end:Heavy_Chain_End[u]=Heavy_Con;}inline long long Query(long long u){Chain *tp;long long minx,maxx;if(u==C_root) return Segement_Query(1,1,Heavy_Con);if(Heavy_Chain_Place[u]<=Heavy_Chain_Place[C_root]&&Heavy_Chain_Place[C_root]<=Heavy_Chain_End[u]) { for(tp=Son[u];tp;tp=tp->next) if(Heavy_Chain_Place[tp->other]<=Heavy_Chain_Place[C_root]&&Heavy_Chain_Place[C_root]<=Heavy_Chain_End[tp->other]) { minx=Heavy_Chain_Place[tp->other]; maxx=Heavy_Chain_End[tp->other];break; }return min(Segement_Query(1,1,minx-1),Segement_Query(1,maxx+1,Heavy_Con)); }else return Segement_Query(1,Heavy_Chain_Place[u],Heavy_Chain_End[u]);}inline long long LCA(long long a,long long b){while(Heavy_Chain_Node[Heavy_Chain_Begin[a]]!=Heavy_Chain_Node[Heavy_Chain_Begin[b]]&&a!=root&&b!=root) if(deep[f[Heavy_Chain_Node[Heavy_Chain_Begin[a]]]]>=deep[f[Heavy_Chain_Node[Heavy_Chain_Begin[b]]]]) a=f[Heavy_Chain_Node[Heavy_Chain_Begin[a]]]; else b=f[Heavy_Chain_Node[Heavy_Chain_Begin[b]]]; return deep[a]>deep[b]?b:a;}inline void Change(long long a,long long b){ long long data; read(data);long long ancestor=LCA(a,b); while(a!=ancestor){if(Heavy_Chain_Begin[a]==Heavy_Chain_Begin[ancestor]) {Segement_Change(1,Heavy_Chain_Place[ancestor],Heavy_Chain_Place[a],data);break ;} Segement_Change(1,Heavy_Chain_Begin[a],Heavy_Chain_Place[a],data); a=f[Heavy_Chain_Node[Heavy_Chain_Begin[a]]];}while(b!=ancestor){if(Heavy_Chain_Begin[b]==Heavy_Chain_Begin[ancestor]) {Segement_Change(1,Heavy_Chain_Place[ancestor],Heavy_Chain_Place[b],data);break ;} Segement_Change(1,Heavy_Chain_Begin[b],Heavy_Chain_Place[b],data); b=f[Heavy_Chain_Node[Heavy_Chain_Begin[b]]];}Segement_Change(1,Heavy_Chain_Place[ancestor],Heavy_Chain_Place[ancestor],data);}inline void addside(long long a,long long b){Chain *tp=new Chain;tp->other=b;tp->next=head[a];head[a]=tp;}int main(){long long n,m,i,j,k,l; read(n),read(m); for(i=2;i<=n;i++) read(j),read(k),addside(j,k),addside(k,j); for(i=1;i<=n;i++)read(Data[i]); read(root),C_root=root; f[root]=root; dfs(root); dfs2(root,1); Build_Segement_Tree(1,1,Heavy_Con);for(i=1;i<=m;i++) { read(j); if(j==1) read(C_root); else if(j==2) read(k),read(l),Change(k,l); else read(k),printf("%lld\n",Query(k)); }return 0;}
0 0
- bzoj3083: 遥远的国度
- [bzoj3083]遥远的国度
- BZOJ3083: 遥远的国度
- bzoj3083 遥远的国度
- BZOJ3083遥远的国度
- 【bzoj3083】 遥远的国度
- 【Bzoj3083】遥远的国度
- bzoj3083 遥远的国度
- 【bzoj3083】【遥远的国度】【树链剖分】
- 【BZOJ3083】遥远的国度,树链剖分练习
- BZOJ3083——遥远的国度
- bzoj3083 遥远的国度 树链剖分+线段树
- bzoj3083 遥远的国度 树链剖分+树上lca
- [BZOJ3083]遥远的国度-树链剖分-线段树
- bzoj3083遥远的国度 树链剖分+线段树
- [bzoj3083][树链剖分][lca]遥远的国度
- [BZOJ3083]遥远的国度(链剖+dfs序)
- 遥远国度的呼唤
- 如何安装TESIS DYNAware
- 剑指Offer·第一章
- lua的metatable讲解
- Ant的build.xml脚本模板
- Sublime Text 3 常用插件以及安装方法
- BZOJ3083: 遥远的国度
- 内容提供者
- 053-18 What two statements are true regarding the recommendations received from the SQL Access Advi
- Frama-C news and ideas
- linux中shell常用联合批量操作命令
- iOS开发小技巧:刷新UITableView
- 关于storyboard、xib和纯代码的混用
- 八大排序算法图文动态 讲解
- python函数日积月累 basestring()、any()、all()、callable()、divmod()