码迷,mamicode.com
首页 > 其他好文 > 详细

树链剖分第一发HDU 3966

时间:2016-04-10 17:44:07      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

好几周之前学长讲了树链剖分(ps:我记得讲的时间超级短,大概不到二十分钟就讲完了~_~,那时候学长说好简单,,,,现在看起来确实不是很难)

HDU 3966

题意:

  给了一个树和各个点的权值,不超过五万个点,有以下三种操作,操作数不超过十万

  I a b w :(I是字符"I",a,b,w是数字)表示从 a 到 b 的路径上的点的权值都加上 w 

  D a b w :从 a 到 b 的路径上的点的权值都减去 w 

  Q a : 询问点 a 的权值是多少

 

这是一个树链剖分的裸题~笨宝宝wa(MLE,TLE,RE)了好多好多次~~~

树链剖分参考博客 呜呜呜~这篇博客非常棒~尤其是他的例子的那个图

 

莫名其妙的超空间

莫名其妙的超时

re是因为数组开小了~

 

附代码:

技术分享
  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <iostream>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <cstring>
  6 #include <algorithm>
  7 using namespace std ;
  8 #define LL long long
  9 #define rep(i,n) for (int i = 1 ; i <= n ; ++ i)
 10 
 11 const int maxn = 100010 ;
 12 int N , R , QAQ , h[maxn] , to[maxn] , nxt[maxn] , val[maxn] , cnt , id ;
 13 int dep[maxn] , siz[maxn] , son[maxn] , fa[maxn] ;
 14 int top[maxn] , pos[maxn] , rk[maxn] ;
 15 void Init()
 16 {
 17     memset(h,-1,sizeof(h)) ;
 18     memset(son,-1,sizeof(son)) ;
 19     cnt = id = 0 ;
 20     fa[1] = 1 ;
 21 }
 22 
 23 inline void addedge(int u,int v)
 24 {
 25     to[cnt] = v , nxt[cnt] = h[u] , h[u] = cnt ++ ;
 26     to[cnt] = u , nxt[cnt] = h[v] , h[v] = cnt ++ ;
 27 }
 28 void dfsa(int rt,int d)
 29 {
 30     dep[rt] = d , siz[rt] = 1 ;
 31     int v ;
 32     for (int i = h[rt] ; ~i ; i = nxt[i]) {
 33         v = to[i] ;
 34         if (v != fa[rt]) {
 35             fa[v] = rt ;
 36             dfsa(v,d+1) ;
 37             siz[rt] += siz[v] ;
 38             if (son[rt] == -1 || siz[v] > siz[son[rt]]) son[rt] = v ;
 39         }
 40     }
 41 }
 42 
 43 void dfsb(int rt,int tp)
 44 {
 45     pos[rt] = ++ id ;
 46     top[rt] = tp ;
 47     rk[pos[rt]] = rt ;
 48     if (son[rt] == -1) return ;
 49     dfsb(son[rt],tp) ;
 50     int v ;
 51     for (int i = h[rt] ; ~i ; i = nxt[i]) {
 52         v = to[i] ;
 53         if (v != fa[rt] && v != son[rt]) dfsb(v,v) ;
 54     }
 55 }
 56 
 57 struct Node
 58 {
 59     int le , ri , x , tag ;
 60 }A[maxn<<2];
 61 
 62 void Build(int i,int le,int ri)
 63 {
 64     A[i].le = le , A[i].ri = ri ;
 65     A[i].tag = A[i].x = 0 ;
 66     if (le == ri) {
 67         A[i].x = val[rk[le]] ;
 68         return ;
 69     }
 70     int mid = (le+ri)>>1 ;
 71     Build(i<<1,le,mid) ;
 72     Build(i<<1|1,mid+1,ri) ;
 73 }
 74 
 75 void pushDown(int i)
 76 {
 77     if (A[i].tag) {
 78         A[i<<1].tag += A[i].tag ;
 79         A[i<<1].x += A[i].tag ;
 80         A[i<<1|1].tag += A[i].tag ;
 81         A[i<<1|1].x += A[i].tag ;
 82         A[i].tag = 0 ;
 83     }
 84 }
 85 
 86 void update(int i,int le,int ri,int x)
 87 {
 88     if (le < A[i].le || ri > A[i].ri) return ;
 89     if (A[i].le == le && A[i].ri == ri) {
 90         A[i].tag += x , A[i].x += x ;
 91         return ;
 92     }
 93     pushDown(i) ;
 94     int mid = (A[i].le + A[i].ri)>>1 ;
 95     if (ri <= mid) update(i<<1,le,ri,x) ;
 96     else if (le > mid) update(i<<1|1,le,ri,x) ;
 97     else {
 98         update(i<<1,le,mid,x) ;
 99         update(i<<1|1,mid+1,ri,x) ;
100     }
101 }
102 
103 int Query(int i,int p)
104 {
105     if (A[i].le == p && A[i].ri == p) return A[i].x ;
106     pushDown(i) ;
107     int mid = (A[i].le + A[i].ri)>>1 ;
108     if (p <= mid) return Query(i<<1,p) ;
109     else return Query(i<<1|1,p) ;
110 }
111 
112 void solveUpdate(int u,int v,int w)
113 {
114     while (top[u] != top[v]) {
115         if (dep[top[u]] < dep[top[v]]) swap(u,v) ;
116         update(1,pos[top[u]],pos[u],w) ;
117         u = fa[top[u]] ;
118     }
119     if (dep[u] > dep[v]) swap(u,v) ;
120     update(1,pos[u],pos[v],w) ;
121 }
122 
123 int main()
124 {
125  //   freopen("in.txt","r",stdin) ;
126     int u , v , w ;
127     char c ;
128     while (scanf("%d%d%d",&N,&R,&QAQ) == 3) {
129         Init() ;
130         rep(i,N) scanf("%d",&val[i]) ;
131         rep(i,R) {
132             scanf("%d%d",&u,&v) ;
133             addedge(u,v) ;
134         }
135         dfsa(1,1) ;
136         dfsb(1,1) ;
137         Build(1,1,N) ;
138         while (QAQ --) {
139             c = getchar() ;
140             while (c != I && c != D && c != Q) c = getchar() ;
141             if (c == Q) {
142                 scanf("%d",&w) ;
143                 printf("%d\n",Query(1,pos[w])) ;
144             }
145             else {
146                 scanf("%d%d%d",&u,&v,&w) ;
147                 if (c == D) w = -w ;
148                 solveUpdate(u,v,w) ;
149             }
150         }
151     }
152     return 0 ;
153 }
hdu3966

 

 

 

~end~

树链剖分第一发HDU 3966

标签:

原文地址:http://www.cnblogs.com/smile-0/p/5374648.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!