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
" :: "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
",doit(x));
114         }
115     }
116     return 0;
117 }
View Code

原文地址:https://www.cnblogs.com/137shoebills/p/7788226.html