JZYZOJ1539[haoi2015]T2 树链剖分
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZYZOJ1539[haoi2015]T2 树链剖分相关的知识,希望对你有一定的参考价值。
http://172.20.6.3/Problem_Show.asp?id=1539
在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分。
oi考试的时候原来不能汇编开栈,只能写手工栈orz,学长说当时省选最高分50,本来以为很简单的题没想到这么套路。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 #define lc x*2 8 #define rc x*2+1 9 const int maxn=100010; 10 int n,m; 11 long long a[maxn]={}; 12 struct nod{ 13 int y,next; 14 }e[maxn*2]; 15 int head[maxn]={},tot=0; 16 long long fa[maxn]={},dep[maxn]={},siz[maxn]={}; 17 long long kid[maxn]={},top[maxn]={},val[maxn]={}; 18 struct seg{ 19 long long l,r,v,w,siz; 20 seg(){l=r=v=w=siz=0;} 21 }t[maxn*4]; 22 void init(long long x,long long y){ 23 e[++tot].y=y;e[tot].next=head[x];head[x]=tot; 24 } 25 int build1(int x,int pa){ 26 int y,hug=0,si,tsn=1;fa[x]=pa; 27 for(int i=head[x];i;i=e[i].next){ 28 y=e[i].y; 29 if(y==pa)continue; 30 si=build1(y,x);tsn+=si; 31 if(si>hug)hug=si,kid[x]=y; 32 }return siz[x]=tsn; 33 } 34 void build2(int x,int pa){ 35 int y;dep[x]=++tot;top[x]=pa; 36 val[dep[x]]=a[x]; 37 if(kid[x])build2(kid[x],pa); 38 for(int i=head[x];i;i=e[i].next){ 39 y=e[i].y; 40 if(y==kid[x]||y==fa[x])continue; 41 build2(y,y); 42 } 43 } 44 void pushup(int x){ 45 if(t[x].siz>1)t[x].v=t[lc].v+t[rc].v; 46 t[x].v+=t[x].w*t[x].siz; 47 } 48 void build(int x,int l,int r){ 49 t[x].r=r;t[x].l=l;t[x].siz=r-l+1; 50 if(l==r){t[x].v=val[l];return;} 51 int mid=(l+r)/2; 52 build(lc,l,mid); 53 build(rc,mid+1,r); 54 pushup(x); 55 } 56 void add(int x,int l,int r,long long w){ 57 if(l<=t[x].l&&t[x].r<=r){ 58 if(t[x].l==t[x].r)t[x].v+=w; 59 else t[x].w+=w;pushup(x); 60 return; 61 } 62 int mid=(t[x].l+t[x].r)/2; 63 if(l<=mid)add(lc,l,r,w); 64 if(r>mid)add(rc,l,r,w); 65 pushup(x); 66 } 67 long long sum(int x,int l,int r,long long w){ 68 if(l<=t[x].l&&t[x].r<=r){ 69 return t[x].v+t[x].siz*w; 70 } 71 int mid=(t[x].l+t[x].r)/2;long long ans=0; 72 if(l<=mid)ans+=sum(lc,l,r,w+t[x].w); 73 if(r>mid)ans+=sum(rc,l,r,w+t[x].w); 74 return ans; 75 } 76 long long doit(int x){ 77 int a=top[x];long long ans=0; 78 while(a!=1){ 79 ans+=sum(1,dep[a],dep[x],0); 80 x=fa[a];a=top[x]; 81 } 82 ans+=sum(1,dep[a],dep[x],0); 83 return ans; 84 } 85 long long read(){ 86 char ch=getchar();long long x=0,f=1; 87 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 88 while(ch>=‘0‘&&ch<=‘9‘){x*=10;x+=ch-‘0‘;ch=getchar();} 89 return x*f; 90 } 91 int main(){ 92 //freopen("wtf.in","r",stdin); 93 int size = 256 << 20; // 256MB 94 char *p = (char*)malloc(size) + size; 95 __asm__("movl %0, %%esp\n" :: "r"(p)); 96 n=read();m=read();int x,y,v; 97 for(int i=1;i<=n;i++)a[i]=read(); 98 for(int i=1;i<n;i++){x=read();y=read();init(x,y);init(y,x);} 99 tot=0;build1(1,1);build2(1,1); 100 build(1,1,n); 101 for(int i=1;i<=m;i++){ 102 scanf("%d",&v); 103 if(v==1){ 104 scanf("%d%d",&x,&y); 105 add(1,dep[x],dep[x],y); 106 } 107 else if(v==2){ 108 scanf("%d%d",&x,&y); 109 add(1,dep[x],dep[x]+siz[x]-1,y); 110 } 111 else{ 112 scanf("%d",&x); 113 printf("%I64d\n",doit(x)); 114 } 115 } 116 return 0; 117 }
以上是关于JZYZOJ1539[haoi2015]T2 树链剖分的主要内容,如果未能解决你的问题,请参考以下文章
数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
cogs 1963. [HAOI 2015] 树上操作 树链剖分+线段树
JZYZOJ1544 [haoi2016T2]放棋子 错排公式 组合数学 高精度
JZYZOJ 1542 [haoi2015]str 矩阵乘法 dp