1. 程式人生 > >[bzoj] 1036 Count

[bzoj] 1036 Count

truct == oid define struct bzoj wap pat using

原題

樹鏈剖分板子題

樹剖詳解:

#include<cstdio>
#include<algorithm>
typedef long long ll;
#define N 30010
using namespace std;
int n,x,y,m,a[N],f[N],dfn[N],deep[N],head[N],cnt=1,tp[N],ref[N],t,son[N],size[N];
char s[10];
struct hhh
{
    int to,next;
}edge[2*N];
struct node
{
    int l,r,data,mx;
}tre[4*N];

int
read() { int ans=0,fu=1; char j=getchar(); for (;(j<‘0‘ || j>‘9‘) && j!=‘-‘;j=getchar()) ; if (j==‘-‘) fu=-1,j=getchar(); for (;j>=‘0‘ && j<=‘9‘;j=getchar()) ans*=10,ans+=j-‘0‘; return ans*fu; } void add(int u,int v) { edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } void
dfs1(int x,int fa,int dep) { f[x]=fa; deep[x]=dep+1; int mx=0; for (int i=head[x],v;i;i=edge[i].next) { v=edge[i].to; if (v!=fa) { dfs1(v,x,dep+1); size[x]+=size[v]; if (size[v]>mx) son[x]=v,mx=size[v]; } } size[x]++; } void dfs2(int
x,int top) { dfn[x]=++t; ref[t]=x; tp[x]=top; if (son[x]) dfs2(son[x],top); for (int i=head[x],v;i;i=edge[i].next) { v=edge[i].to; if (v!=son[x] && v!=f[x]) dfs2(v,v); } } void build(int i,int l,int r) { tre[i].l=l; tre[i].r=r; if (l==r) { tre[i].data=a[ref[l]]; tre[i].mx=a[ref[l]]; return ; } int mid=(l+r)>>1; build(i*2,l,mid); build(i*2+1,mid+1,r); tre[i].data=tre[i*2].data+tre[i*2+1].data; tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx); } void modify(int i,int x,int y) { if (tre[i].l==x && tre[i].l==tre[i].r) { tre[i].data=y; tre[i].mx=y; return ; } int mid=(tre[i].l+tre[i].r)>>1; if (x>mid) modify(i*2+1,x,y); else modify(i*2,x,y); tre[i].data=tre[i*2].data+tre[i*2+1].data; tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx); } ll query(int i,int l,int r,int p) { if (tre[i].l==l && tre[i].r==r) if (p) return tre[i].data; else return tre[i].mx; int mid=(tre[i].l+tre[i].r)>>1; if (l>mid) return query(i*2+1,l,r,p); else if (r<=mid) return query(i*2,l,r,p); else if (p) return query(i*2,l,mid,p)+query(i*2+1,mid+1,r,p); else return max(query(i*2,l,mid,p),query(i*2+1,mid+1,r,p)); } ll pathquery(int u,int v,int p) { ll ans=0,tmp=-1000000000; while (tp[u]!=tp[v]) { if (deep[tp[u]]<deep[tp[v]]) swap(u,v); if (p) ans+=query(1,dfn[tp[u]],dfn[u],p); else tmp=max(tmp,query(1,dfn[tp[u]],dfn[u],p)); u=f[tp[u]]; } if (deep[u]>deep[v]) swap(u,v); if (p) return ans+query(1,dfn[u],dfn[v],p); else return max(tmp,query(1,dfn[u],dfn[v],p)); } int main() { n=read(); for (int i=1;i<n;i++) { x=read(); y=read(); add(x,y); add(y,x); } for (int i=1;i<=n;i++) a[i]=read(); dfs1(1,0,0); dfs2(1,1); build(1,1,n); m=read(); while (m--) { scanf("%s",s); x=read(); y=read(); if (s[1]==‘M‘) printf("%lld\n",pathquery(x,y,0)); else if (s[1]==‘S‘) printf("%lld\n",pathquery(x,y,1)); else modify(1,dfn[x],y); } return 0; }

[bzoj] 1036 Count