[bzoj1036]:[ZJOI2008]树的统计Count(树链剖分)
2017-09-30 12:23
441 查看
传送门
十分裸的一个树链剖分,这也是我第一次过树剖题,好激动!
关于这个算法我不多说,自己百度。
代码:
十分裸的一个树链剖分,这也是我第一次过树剖题,好激动!
关于这个算法我不多说,自己百度。
代码:
/************************************************************** Problem: 1036 User: stone41123 Language: C++ Result: Accepted Time:2484 ms Memory:5676 kb ****************************************************************/ #include<bits/stdc++.h> #define ll long long using namespace std; inline int read(){ int x=0;char ch=' ';int f=1; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')f=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; } struct edge{ int to,next; }e[60001]; int n,tot,q; int v[30001]; int head[30001]; inline void addedge(int x,int y){ e[++tot].to=y;e[tot].next=head[x];head[x]=tot; } int father[30001]; int size[30001]; int top[30001]; int heavy[30001]; int dep[30001]; void dfs1(int x,int fa){ father[x]=fa; size[x]=1; dep[x]=dep[fa]+1; for(int i=head[x];i;i=e[i].next){ int u=e[i].to; if(u==fa)continue; dfs1(u,x); size[x]+=size[u]; if(size[u]>size[heavy[x]]){ heavy[x]=u; } } } int a[30001]; int mp[30001]; int cnt; int id[30001]; void dfs2(int x,int first){ top[x]=first; id[++cnt]=x; mp[x]=cnt; a[cnt]=v[x]; if(size[x]==1){ return; } dfs2(heavy[x],first); for(int i=head[x];i;i=e[i].next){ int u=e[i].to; if(u==heavy[x]||u==father[x]){ continue; } dfs2(u,u); } } int sum[30001*4]; int mx[30001*4]; inline void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); } void build(int rt,int l,int r){ if(l==r){ sum[rt]=mx[rt]=a[l]; return; } int mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt); } void update(int rt,int l,int r,int pos,int x){ if(l==r){ sum[rt]=mx[rt]=x; return; } int mid=(l+r)>>1; if(pos<=mid)update(rt<<1,l,mid,pos,x); else update(rt<<1|1,mid+1,r,pos,x); pushup(rt); } int qmax(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ return mx[rt]; } int mid=(l+r)>>1; int ans=-0x7fffffff; if(L<=mid)ans=max(ans,qmax(rt<<1,l,mid,L,R)); if(mid+1<=R)ans=max(ans,qmax(rt<<1|1,mid+1,r,L,R)); return ans; } int qsum(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ return sum[rt]; } int mid=(l+r)>>1; int ans=0; if(L<=mid)ans+=qsum(rt<<1,l,mid,L,R); if(mid+1<=R)ans+=qsum(rt<<1|1,mid+1,r,L,R); return ans; } int query_max(int x,int y){ int ans=-0x7fffffff; int tx=top[x]; int ty=top[y]; while(tx!=ty){ if(dep[tx]<dep[ty]){ swap(x,y);swap(tx,ty); } ans=max(ans,qmax(1,1,n,mp[tx],mp[x])); x=father[tx]; tx=top[x]; } if(dep[x]<dep[y]){ swap(x,y);swap(tx,ty); } return max(ans,qmax(1,1,n,mp[y],mp[x])); } int query_sum(int x,int y){ int ans=0; int tx=top[x]; int ty=top[y]; while(tx!=ty){ if(dep[tx]<dep[ty]){ swap(x,y);swap(tx,ty); } ans+=qsum(1,1,n,mp[tx],mp[x]); x=father[tx]; tx=top[x]; } if(dep[x]<dep[y]){ swap(x,y);swap(tx,ty); } return ans+qsum(1,1,n,mp[y],mp[x]); } int main(){ n=read(); for(int i=1;i<n;i++){ int x=read(),y=read(); addedge(x,y);addedge(y,x); } for(int i=1;i<=n;i++)v[i]=read(); q=read(); dfs1(1,0); dfs2(1,1); build(1,1,n); char cmp0[20]="CHANGE"; char cmp1[20]="QMAX"; char cmp2[20]="QSUM"; for(int i=1;i<=q;i++){ char s[20]; scanf("%s",s); if(strcmp(cmp0,s)==0){ int pos=read(),x=read(); update(1,1,n,mp[pos],x); } else if(strcmp(cmp1,s)==0){ int x=read(),y=read(); printf("%d\n",query_max(x,y)); } else{ int x=read(),y=read(); printf("%d\n",query_sum(x,y)); } } return 0; }
相关文章推荐
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- 【树链剖分+线段树】BZOJ1036 [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分(点权))
- BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分 点权)
- 【BZOJ 1036】[ZJOI2008]树的统计Count 【树链剖分+线段树】
- BZOJ1036:[ZJOI2008]树的统计Count 树链剖分 / LCT
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分 + 线段树)
- 【树链剖分/线段树】BZOJ1036-[ZJOI2008]树的统计Count
- bzoj 1036: [ZJOI2008]树的统计Count(树链剖分 点权)
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
- BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】
- bzoj 1036 [ZJOI2008]树的统计Count 树链剖分
- |BZOJ 1036|树链剖分|线段树|[ZJOI2008]树的统计Count
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count 树链剖分
- BZOJ 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
- bzoj1036 [ZJOI2008]树的统计Count (树链剖分|Link Cut Tree)
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分裸题)
- BZOJ 1036 [ZJOI2008] 树的统计Count (树链剖分)
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)