hdu 3966 树链剖分(坑内存)

来源:互联网 发布:淘宝接单app软件 编辑:程序博客网 时间:2024/06/10 10:24
//hdu 3966 树链剖分+树状数组(节点)#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <algorithm>#include <iostream>#include <string.h>#include <vector>#define lowbit(x) ((x)&(-x))#define LL long long#define maxn 50005using namespace std;int top[maxn],fa[maxn],son[maxn],siz[maxn],dep[maxn],s[maxn],n,v[maxn],t[maxn],z;vector<int> g[maxn];inline void add (int x, int v) {    while (x <= n) {        t[x] += v;        x += lowbit(x);    }}inline void add (int l, int r, int v) {    add(l, v);    add(r+1, -v);}inline int query (int x) {    int ret = 0;    while (x) {        ret += t[x];        x -= lowbit(x);    }    return ret;}void change(int a,int b,int c){    int aa=top[a],bb=top[b];    while(aa!=bb)    {        if(dep[aa]<dep[bb])        {            swap(aa,bb);            swap(a,b);        }        add(s[aa],s[a],c);        a=fa[aa];        aa=top[a];    }    if(dep[a]<dep[b])       swap(a,b);    add(s[b],s[a],c);}void dfs(int a,int b,int c){    siz[a]=1;    dep[a]=c;    son[a]=0;    fa[a]=b;    for(int i=0;i<g[a].size();i++)    {        int j=g[a][i];        if(j==b)            continue;        dfs(j,a,c+1);        siz[a]+=siz[j];        if(siz[j]>siz[son[a]])           son[a]=j;    }}/*void dfs(int a,int b){    siz[a]=1;    for(int i=0;i<g[a].size();i++)    {        int j=g[a][i];        if(j==b)            continue;        fa[j]=a;        dep[j]=dep[a]+1;        dfs(j,a);        siz[a]+=siz[j];        if(siz[j]>siz[son[a]])           son[a]=j;    }}*///不知道为什么这种写法会爆内存,不科学void build(int a,int b){    s[a]=++z;    top[a]=b;    if(son[a])        build(son[a],b);    for(int i=0;i<g[a].size();i++)    {        int j=g[a][i];        if(j==son[a]||j==fa[a])           continue;        build(j,j);    }}int main () {    int m,q;    //freopen("d:\\in.txt","r",stdin);    while (scanf("%d%d%d", &n, &m, &q) == 3) {        z=0;        memset(t, 0, sizeof(t));        for (int i = 1; i <= n; i++) {            scanf("%d", &v[i]);            g[i].clear();        }        int a, b, c;        for (int i = 0; i < m; i++) {            scanf("%d%d", &a, &b);            g[a].push_back(b);            g[b].push_back(a);        }        dfs(1,-1,0);        //dfs(1, -1);        build(1, 1);        for (int i = 1; i <= n; i++)            add(s[i],s[i],v[i]);        char op[5];        while (q--) {            scanf("%s%d", op, &a);            if (op[0] == 'Q')                printf("%d\n", query(s[a]));            else {                scanf("%d%d", &b, &c);                if (op[0] == 'D') c = -c;                change(a, b, c);            }        }    }    return 0;}

0 0