[dfs序 树状数组] BZOJ 4034 [HAOI2015]T2

来源:互联网 发布:大班美工多彩的剪纸 编辑:程序博客网 时间:2024/05/02 01:28

两个log可以树链剖分

day2听课时惊闻一个log的做法

但我打low了,并不快...




#include<cstdio>#include<cstdlib>#include<algorithm>#define V G[p].vusing namespace std;typedef long long ll;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(ll &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void write(ll x){char s[50],len=0;if (x==0) { putchar('0'); return; }if (x<0) putchar('-'),x=-x;while (x) s[++len]=x%10+'0',x/=10;for (int i=len;i;i--) putchar(s[i]);}const int N=100005;#define lowbit(x) ((x)&-(x))struct BIT{ll maxn,c[N];inline void init(int n){maxn=n;}inline void add(ll x,ll r){for (int i=x;i<=maxn;i+=lowbit(i))c[i]+=r;}inline void add(ll l,ll r,ll x){add(l,x); add(r+1,-x);}inline ll query(ll x){ll ret=0;for (int i=x;i;i-=lowbit(i))ret+=c[i];return ret;}}bit1,bit2;struct edge{int u,v,next;};edge G[N*2];int head[N],num;inline void add(int u,int v,int p){G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}ll n,Q,w[N];int clk,size[N],fat[N],depth[N],tid[N],last[N];inline int dfs(int u,int fa){size[u]=1; fat[u]=fa; depth[u]=depth[fa]+1; tid[u]=++clk;for (int p=head[u];p;p=G[p].next)if (V!=fa)size[u]+=dfs(V,u);last[u]=tid[u]+size[u]-1;return size[u];}int main(){ll x,y,order,ans;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(Q); bit1.init(n); bit2.init(n);for (int i=1;i<=n;i++) read(w[i]);for (int i=1;i<n;i++) read(x),read(y),add(x,y,++num),add(y,x,++num);dfs(1,0);for (int i=1;i<=n;i++) bit1.add(tid[i],last[i],w[i]);while (Q--){read(order);if (order==1){read(x); read(y);bit1.add(tid[x],last[x],y);}else if (order==2){read(x); read(y);bit1.add(tid[x],last[x],-(depth[x]-1)*y);bit2.add(tid[x],last[x],y);}else if (order==3){read(x);write(bit1.query(tid[x])+bit2.query(tid[x])*depth[x]); putchar('\n');}}return 0;}


0 0