bzoj4034
http://www.lydsy.com/JudgeOnline/problem.php?id=4034
树链剖分。
跟NOI2015的“软件包管理”一模一样。。。。。
河南的爽死了。。。。。。
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define fill(a,l,r,v) fill(a+l,a+r+1,v) #define re(i,a,b) for(i=(a);i<=(b);i++) #define red(i,a,b) for(i=(a);i>=(b);i--) #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } const int maxN=100000; int N,Q; int val[maxN+100]; int now,first[maxN+100]; struct Tedge{int v,next;}edge[2*maxN+100]; inline void addedge(int u,int v){now++;edge[now].v=v;edge[now].next=first[u];first[u]=now;} int head,tail,que[maxN+100]; int fa[maxN+100],size[maxN+100],heavyson[maxN+100],gao[maxN+100]; int cnt,idx[maxN+100],l[maxN+100],r[maxN+100]; int vis[maxN+100],top,sta[maxN+100],last[maxN+100]; inline void build() { int i,j; que[head=tail=1]=1; while(head<=tail) { int u=que[head++],v; for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u])fa[que[++tail]=v]=u; } red(j,tail,1) { int u=que[j],v; size[u]=1; for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u])size[u]+=size[v]; } re(j,1,tail) { int u=que[j],v,heavy=-1; for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u]) if(heavy==-1 || size[heavy]<size[v]) heavy=v; heavyson[u]=heavy; } vis[sta[top=1]=1]=1; last[1]=first[1]; idx[1]=++cnt; gao[1]=1; while(top>=1) { int u=sta[top],i=last[u],v; if(heavyson[u]!=-1 && !vis[heavyson[u]]) { v=heavyson[u]; vis[sta[++top]=v]=1; last[v]=first[v]; idx[v]=++cnt; gao[v]=gao[u]; } else for(v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u] && !vis[v]) { vis[sta[++top]=v]=1; last[v]=first[v]; idx[v]=++cnt; gao[v]=v; last[u]=edge[i].next; break; } if(i==-1)top--; } red(j,tail,1) { int u=que[j],v; l[u]=r[u]=idx[u]; for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u])upmin(l[u],l[v]),upmax(r[u],r[v]); } } struct Ttree{LL v,add;}tr[4*maxN+1000]; inline void down(int rt,int l,int r,int mid) { if(tr[rt].add==0)return; LL add=tr[rt].add; tr[rt*2].add+=add;tr[rt*2].v+=add*LL(mid-l+1); tr[rt*2+1].add+=add;tr[rt*2+1].v+=add*LL(r-mid); tr[rt].add=0; } inline void update(int rt,int l,int r,int x,int y,LL val) { if(l>r || x>y || y<l || r<x)return; if(x<=l && r<=y){tr[rt].add+=val;tr[rt].v+=val*LL(r-l+1);return;} int mid=(l+r)>>1; down(rt,l,r,mid); update(rt*2,l,mid,x,y,val); update(rt*2+1,mid+1,r,x,y,val); tr[rt].v=tr[rt*2].v+tr[rt*2+1].v; } inline LL ask(int rt,int l,int r,int x,int y) { if(l>r || x>y || y<l || r<x)return 0; if(x<=l && r<=y)return tr[rt].v; int mid=(l+r)>>1; down(rt,l,r,mid); return ask(rt*2,l,mid,x,y)+ask(rt*2+1,mid+1,r,x,y); } inline LL query(int x) { LL res=0; while(x) { res+=ask(1,1,N,idx[gao[x]],idx[x]); x=fa[gao[x]]; } return res; } int main() { freopen("bzoj4034.in","r",stdin); freopen("bzoj4034.out","w",stdout); int i; N=gint();Q=gint(); re(i,1,N)val[i]=gint(); now=-1;mmst(first,-1); re(i,1,N-1){int u=gint(),v=gint();addedge(u,v);addedge(v,u);} build(); re(i,1,N)update(1,1,N,idx[i],idx[i],LL(val[i])); while(Q--) { int type=gint(),x,a; switch(type) { case 1: x=gint();a=gint(); update(1,1,N,idx[x],idx[x],LL(a)); break; case 2: x=gint();a=gint(); update(1,1,N,l[x],r[x],LL(a)); break; case 3: x=gint(); //PF("%lld\n",query(x)); cout<<query(x)<<endl; break; } } return 0; }