好几周之前学长讲了树链剖分(ps:我记得讲的时间超级短,大概不到二十分钟就讲完了~_~,那时候学长说好简单,,,,现在看起来确实不是很难)
题意:
给了一个树和各个点的权值,不超过五万个点,有以下三种操作,操作数不超过十万
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~
时间: 2024-10-11 13:18:32