[HAOI2015]树上操作 -树链剖分

来源:互联网 发布:sql server 查询二进制 编辑:程序博客网 时间:2024/05/21 10:14
                                     1963. [HAOI2015]树上操作

 

【题目描述】

有一棵点数为N的树,以点1为根,且树点有权值。然后有M个操作,分为三种:

操作1:把某个节点x的点权增加a。

操作2:把某个节点x为根的子树中所有点的点权都增加a。

操作3:询问某个节点x到根的路径中所有点的点权和。

【输入格式】

第一行两个整数N,M,表示点数和操作数。

接下来一行N个整数,表示树中节点的初始权值。

接下来N-1行每行两个正整数fr,to,表示该树中存在一条边(fr,to)。

再接下来M行,每行分别表示一次操作。其中第一个数表示该操作的种类(1~3),之后接这个操作的参数(x或者x a)。

【输出格式】

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

【样例输入】

5 5

1 2 3 4 5

1 2

1 4

2 3

2 5

3 3

1 2 1

3 5

2 1 2

3 3

【样例输出】

6

9

13

【提示】

对于30%的数据,N,M<=1000

对于50%的数据,N,M<=100000且数据随机。

对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。

 

注意long long就好了 

把它当做树剖模板来做,听说并查集也能做

 

  1 #include <ctype.h>  2 #include <cstdio>  3   4 typedef long long LL;  5   6 const int MAXN=100010;  7   8 int n,m,inr;  9  10 LL a[MAXN]; 11  12 struct SegmentTree { 13     int l,r; 14     LL val,tag; 15 }; 16 SegmentTree t[MAXN<<2]; 17  18 struct data { 19     int to; 20     int next; 21 }; 22 data E[MAXN*10]; 23  24 int head[MAXN<<1],tot; 25  26 int siz[MAXN],son[MAXN],fa[MAXN],id[MAXN],dep[MAXN],top[MAXN],rank[MAXN],mx[MAXN]; 27  28 inline void read(int&x) { 29     int f=1;register char c=getchar(); 30     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 31     for(;isdigit(c);x=x*10+c-48,c=getchar()); 32     x=x*f; 33 } 34  35 inline void readl(LL&x) { 36     int f=1;register char c=getchar(); 37     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 38     for(;isdigit(c);x=x*10+c-48,c=getchar()); 39     x=x*f; 40 } 41  42 inline void add(int x,int y) { 43     E[++tot].to=y; 44     E[tot].next=head[x]; 45     head[x]=tot; 46 } 47  48 inline int max(int a,int b) { 49     return a<b?b:a; 50 } 51  52 inline void swap(int&x,int&y) { 53     int t=x;x=y;y=t; 54     return; 55 } 56  57 inline void dfs_1(int now,int f) { 58     dep[now]=dep[f]+1; 59     siz[now]=1; 60     fa[now]=f; 61     for(register int i=head[now];i;i=E[i].next) { 62         int to=E[i].to; 63         if(to==f) continue; 64         dfs_1(to,now); 65         siz[now]+=siz[to]; 66         if(son[now]==-1||siz[son[now]]<siz[to]) son[now]=to; 67     } 68 } 69  70 inline void dfs_2(int now,int sym) { 71     id[now]=++inr; 72     top[now]=sym; 73     rank[id[now]]=now; 74     if(son[now]==-1) return; 75     dfs_2(son[now],sym); 76     for(int i=head[now];i;i=E[i].next) { 77         int to=E[i].to; 78         if(to!=son[now]&&to!=fa[now]) 79           dfs_2(to,to); 80     } 81     return; 82 } 83  84 inline void build_tree(int now,int l,int r) { 85     t[now].l=l,t[now].r=r; 86     if(l==r) { 87         t[now].val=a[rank[l]]; 88         return; 89     } 90     int mid=(l+r)>>1; 91     build_tree(now<<1,l,mid); 92     build_tree(now<<1|1,mid+1,r); 93     t[now].val=t[now<<1].val+t[now<<1|1].val; 94 } 95  96 inline void down(int now) { 97     t[now<<1].val+=(t[now<<1].r-t[now<<1].l+1)*t[now].tag; 98     t[now<<1|1].val+=(t[now<<1|1].r-t[now<<1|1].l+1)*t[now].tag; 99     t[now<<1].tag+=t[now].tag;100     t[now<<1|1].tag+=t[now].tag;101     t[now].tag=0;102 }103 104 inline void modify(int now,int l,int r,LL val) {105     if(l<=t[now].l&&r>=t[now].r) {106         t[now].tag+=val;107         t[now].val+=(t[now].r-t[now].l+1)*val;108         return;109     }110     down(now);111     int mid=(t[now].l+t[now].r)>>1;112     if(l<=mid) modify(now<<1,l,r,val);113     if(r>mid) modify(now<<1|1,l,r,val);114     t[now].val=t[now<<1].val+t[now<<1|1].val;115 }116 117 inline LL query(int now,int l,int r) {118     LL ans=0;119     if(l<=t[now].l&&r>=t[now].r) return t[now].val;120     down(now);121     int mid=(t[now].l+t[now].r)>>1;122     if(l<=mid) ans+=query(now<<1,l,r);123     if(r>mid) ans+=query(now<<1|1,l,r);124     return ans;125 }126 127 inline LL Pre_query(int u,int v) {128     LL ans=0;129     while(top[u]!=top[v]) {130         if(dep[top[u]]<dep[top[v]]) swap(u,v);131         ans+=query(1,id[top[u]],id[u]);132         u=fa[top[u]];133     }134     if(dep[u]<dep[v]) swap(u,v);135     ans+=query(1,id[v],id[u]);136     return ans;137 }138 139 int hh() {140     freopen("haoi2015_t2.in","r",stdin);141     freopen("haoi2015_t2.out","w",stdout);142     int x,y,opt;143     read(n);read(m);144     for(register int i=1;i<=n;++i) son[i]=-1,readl(a[i]);145     for(register int i=1;i<n;++i) {146         read(x);read(y);147         add(x,y);add(y,x);148     }149     dfs_1(1,0);150     dfs_2(1,1);151     build_tree(1,1,inr);152     LL p;153     for(register int i=1;i<=m;++i) {154         read(opt);read(x);155             if(opt==1) {156                 readl(p);157                 modify(1,id[x],id[x],p);158             }159             else if(opt==2) {160                 readl(p);161                 modify(1,id[x],id[x]+siz[x]-1,p);162             }163             else {164                 LL ans=Pre_query(1,x);165                 printf("%lld\n",ans);166             }167     }168     return 0;169 }170 171 int sb=hh();172 int main() {;}
代码

 

原创粉丝点击