洛谷 P3258 [JLOI2014]松鼠的新家
阿新 • • 發佈:2018-07-09
update 路徑 eof show define www. max 一個 jloi2014
樹剖,裸題,鑒定完畢。
我是題面
讀完題,恩,樹剖,裸題,沒勁。
處理很簡單,既然每到一個房間吃一塊糖,那麽就在每條路徑上的每個房間放一顆糖,但是每條路徑的終點也就是下一條路徑的起點,在這裏只能加一次,所以別忘記處理完再-1,又因為最後一個點不需要糖,所以直接每條路徑的終點的糖-1即可
上代碼
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cctype> #define ll long long #define gc() getchar() #define maxn 300005 using namespace std; inline ll read(){ ll a=0;int f=0;char p=gc(); while(!isdigit(p)){f|=p=='-';p=gc();} while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();} return f?-a:a; } void write(ll a){ if(a>9)write(a/10); putchar(a%10+'0'); } int n,m,a[maxn]; int tot,head[maxn]; struct ahaha1{ int to,next; }e[maxn<<1]; inline void add(int u,int v){ e[tot].to=v;e[tot].next=head[u];head[u]=tot++; } int sz[maxn],dep[maxn],son[maxn],f[maxn]; void dfs(int u,int fa){ int maxa=0;sz[u]=1; for(int i=head[u];~i;i=e[i].next){ int v=e[i].to;if(v==fa)continue; f[v]=u;dep[v]=dep[u]+1; dfs(v,u);sz[u]+=sz[v]; if(maxa<sz[v])maxa=sz[v],son[u]=v; } } int top[maxn],in[maxn],b[maxn]; void dfs(int u,int fa,int topf){ top[u]=topf;in[u]=++tot;b[tot]=u; if(!son[u])return; dfs(son[u],u,topf); for(int i=head[u];~i;i=e[i].next){ int v=e[i].to;if(v==fa||v==son[u])continue; dfs(v,u,v); } } #define lc p<<1 #define rc p<<1|1 struct ahaha2{ ll v,lz; }t[maxn<<2]; inline void pushup(int p){ t[p].v=t[lc].v+t[rc].v; } inline void pushdown(int p,int l,int r){ int m=l+r>>1; t[lc].v+=t[p].lz*(m-l+1);t[lc].lz+=t[p].lz; t[rc].v+=t[p].lz*(r-m);t[rc].lz+=t[p].lz; t[p].lz=0; } void update(int p,int l,int r,int L,int R){ if(l>R||r<L)return; if(L<=l&&r<=R){t[p].v+=r-l+1;t[p].lz++;return;} int m=l+r>>1;if(t[p].lz)pushdown(p,l,r); update(lc,l,m,L,R);update(rc,m+1,r,L,R); pushup(p); } void update2(int p,int l,int r,int L){ if(l==r){t[p].v--;return;} int m=l+r>>1;if(t[p].lz)pushdown(p,l,r); if(m>=L)update2(lc,l,m,L); else update2(rc,m+1,r,L); pushup(p); } ll query(int p,int l,int r,int L){ if(l==r)return t[p].v; int m=l+r>>1;if(t[p].lz)pushdown(p,l,r); if(m>=L)return query(lc,l,m,L); else return query(rc,m+1,r,L); } inline void solve_1(int x,int y){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); update(1,1,n,in[top[x]],in[x]); x=f[top[x]]; } if(dep[x]>dep[y])swap(x,y); update(1,1,n,in[x],in[y]); } int main(){memset(head,-1,sizeof head); n=read(); for(int i=1;i<=n;++i)a[i]=read(); for(int i=1;i<n;++i){ int x=read(),y=read(); add(x,y);add(y,x); } tot=0;dfs(1,-1);dfs(1,-1,1); for(int i=2;i<=n;++i) solve_1(a[i-1],a[i]),update2(1,1,n,in[a[i]]); for(int i=1;i<=n;++i) write(query(1,1,n,in[i])),putchar('\n'); return 0; }
洛谷 P3258 [JLOI2014]松鼠的新家