【HDU】3966 Aragorn's Story(树链剖分+线段树)
2015-03-27 15:33
309 查看
树链剖分的模板题,思路就不说了, 等做了一些题目之后,在写个总结吧。
先说一下这道题错误的地方。
1、爆栈。看大神的博客才找到解决的方法。
说是hdu的oj是window的系统,容易爆栈
所以在之前应该要手动扩栈。
在代码之前加上:#pragma comment(linker, "/STACK:1024000000,1024000000")就可以了。
2、
是在路径的缩短中写错了。
int fu = top[u], fv = top[v];//这条重链的顶端
一开始写成pre数组,结果就wa了。
先说一下这道题错误的地方。
1、爆栈。看大神的博客才找到解决的方法。
说是hdu的oj是window的系统,容易爆栈
所以在之前应该要手动扩栈。
在代码之前加上:#pragma comment(linker, "/STACK:1024000000,1024000000")就可以了。
2、
是在路径的缩短中写错了。
int fu = top[u], fv = top[v];//这条重链的顶端
一开始写成pre数组,结果就wa了。
/* 第一次栈溢出:添加:#pragma comment(linker, "/STACK:1024000000,1024000000")解决! */ #pragma comment(linker, "/STACK:1024000000,1024000000") #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAX 50005 #define ls rt<<1 #define rs ls|1 #define m (l+r)>>1 int sum[MAX << 2]; int p[MAX], head[MAX], posx[MAX], top[MAX], son[MAX], pre[MAX], size[MAX], deep[MAX]; int posx2[MAX]; int cnt, pos; int n, k, q; struct edg{ int v, next; }edge[MAX<<1]; void addedge(int u, int v) { edge[cnt].v = v; edge[cnt].next = head[u]; head[u] = cnt++; } void dfs(int u, int p, int d) { deep[u] = d; size[u] = 1; pre[u] = p; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v != p) { dfs(v, u, d + 1); size[u] += size[v]; if (son[u] == -1 || size[v] > size[son[u]]) son[u] = v; } } } void getpos(int u, int p) { top[u] = p; posx2[pos] = u; posx[u] = pos++; if (son[u] == -1) return; getpos(son[u], p); for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v != son[u] && v != pre[u]) getpos(v, v); } } void ups( int rt) { if (sum[rt]) { sum[ls] += sum[rt]; sum[rs] += sum[rt]; sum[rt] = 0; } } void updata(int L, int R, int c, int l, int r, int rt) { if (L <= l&&r <= R) { sum[rt] += c; return; } ups( rt); int mid = m; if (L <= mid) updata(L, R, c, l, mid, ls); if (mid < R) updata(L, R, c, mid + 1, r, rs); } int query(int q, int l, int r, int rt) { if (l == r) return sum[rt]; ups( rt); int mid = m; if (q <= mid) return query(q, l, mid, ls); else return query(q, mid + 1, r, rs); } void updata(int u, int v, int c) { int fu = top[u], fv = top[v];//这条重链的顶端 while (fu != fv) { if (deep[fu] < deep[fv]) { swap(fu, fv); swap(u, v); } updata(posx[fu], posx[u], c, 0,pos-1, 1); u = pre[fu]; fu = top[u]; } if (u == v) { updata(posx[u], posx[u], c, 0, pos - 1, 1); return; } if (deep[u]>deep[v]) swap(u, v); updata(posx[u], posx[v], c, 0,pos-1, 1); } void init() { cnt = 0; pos = 0; memset(son, -1, sizeof(son)); memset(head, -1, sizeof(head)); } int a[MAX], e[MAX][2]; void build(int l, int r, int rt) { if (l == r) { sum[rt] = a[posx2[l]]; return; } sum[rt] = 0; int mid = m; build(l, mid, ls); build(mid + 1, r, rs); } int main() { while (~scanf("%d%d%d", &n, &k, &q)) { init(); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for (int i = 0; i < k; i++) { scanf("%d%d", &e[i][0], &e[i][1]); addedge(e[i][0], e[i][1]); addedge(e[i][1], e[i][0]); } dfs(1, 1, 0);//这个第二个1写成0或者写成1都是可以的,不过写成1快了400ms getpos(1, 1); build(0, pos - 1, 1); char str[5]; int a, b, c; while (q--) { scanf("%s", str); if (str[0] == 'Q') { scanf("%d", &a); printf("%d\n", query(posx[a], 0,pos-1, 1)); } else { scanf("%d%d%d", &a, &b, &c); if (str[0] == 'D') c = -c; updata(a, b, c); } } } }
相关文章推荐
- HDU 3966 Aragorn's Story(树链剖分+线段树)
- hdu 3966 Aragorn's Story(树链剖分)
- 【HDU】3966 Aragorn's Story 树链剖分
- Aragorn's Story - HDU 3966 树链刨分
- HDU 3966 Aragorn's Story(树链剖分)
- hdu 3966 Aragorn's Story(树链剖分+树状数组)
- HDU 3966 Aragorn's Story(树链剖分 (基于点权,查询单点值,修改路径的上的点权)模板题)
- hdu-3966 Aragorn's Story(树链剖分,点权)
- hdu 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn&#39;s Story --树链剖分
- HDU 3966 Aragorn's Story(树链剖分)
- [HDU 3966] Aragorn's Story 树链剖分
- hdu 3966 Aragorn's Story 树链剖分
- Hdu 3966 Aragorn's Story (树链剖分)
- hdu 3966 Aragorn's Story 树链剖分
- hdu 3966 Aragorn's Story
- HDU 3966 Aragorn's Story(树链剖分+线段树区间更新+手动扩大内存)
- HDU 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story 树链剖分
- HDU 3966 Aragorn's Story(树剖-点)