【HDU】3966 Aragorn's Story(树链剖分+线段树)

来源:互联网 发布:网络骑士流星 编辑:程序博客网 时间:2024/05/18 19:44

树链剖分的模板题,思路就不说了, 等做了一些题目之后,在写个总结吧。

先说一下这道题错误的地方。

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)>>1int 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);elsereturn 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快了400msgetpos(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);}}}}

0 0
原创粉丝点击