[BZOJ1036][ZJOI2008]树的统计Count

来源:互联网 发布:数据库unique 编辑:程序博客网 时间:2024/04/30 20:18

树剖板子题为什么都这么长啊,手痛

改了值没更新,怒WA两发,我不要BZOJ的WA起飞啊

#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <cmath>#include <iostream>#include <algorithm>using namespace std;const int maxn = 30100;struct edge{int v,next;}e[maxn << 1];int h[maxn],num = 0;struct node{int l,r;int x,y;}t[maxn << 1];int tot = 0;int a[maxn];bool vis[maxn];int n,m,u,v,x,y,d,q;int cnt = 0;int fa[maxn];int dep[maxn];int son[maxn];int pos[maxn],ppos[maxn];int top[maxn];int size[maxn];void build_edge(int u,int v){num++;e[num].v = v;e[num].next = h[u];h[u] = num;}void dfs1(int x){dep[x] = dep[fa[x]] + 1;vis[x] = true;size[x] = 1;son[x] = 0;for(int i = h[x]; i; i = e[i].next){if(vis[e[i].v])continue;fa[e[i].v] = x;dfs1(e[i].v);if(size[e[i].v] > size[son[x]])son[x] = e[i].v;size[x] += size[e[i].v];}}void dfs2(int x){vis[x] = true;if(son[fa[x]] == x)top[x] = top[fa[x]];else{top[x] = x;for(int i = x; i; i = son[i]){pos[i] = ++cnt;ppos[cnt] = i;}}for(int i = h[x]; i; i = e[i].next)if(!vis[e[i].v])dfs2(e[i].v);}void build(int p,int l,int r){int mid = l + r >> 1;if(l == r){t[p].x = a[ppos[mid]];t[p].y = a[ppos[mid]];return;}t[p].l = ++tot;t[p].r = ++tot;build(t[p].l,l,mid);build(t[p].r,mid+1,r);t[p].x += t[t[p].l].x + t[t[p].r].x;if(t[t[p].r].y > t[t[p].l].y)t[p].y = t[t[p].r].y;elset[p].y = t[t[p].l].y;}void change(int p,int l,int r){int mid = l + r >> 1;if(l == r){t[p].x += d;t[p].y += d;return;}t[p].x += d;if(q <= mid){change(t[p].l,l,mid);if(t[t[p].r].y > t[t[p].l].y)t[p].y = t[t[p].r].y;elset[p].y = t[t[p].l].y;}else{change(t[p].r,mid+1,r);if(t[t[p].r].y > t[t[p].l].y)t[p].y = t[t[p].r].y;elset[p].y = t[t[p].l].y;}}int getMax(int p,int l,int r,int L,int R){int mid = l + r >> 1;if(l == L && r == R)return t[p].y;if(R <= mid)return getMax(t[p].l,l,mid,L,R);else if(L > mid)return getMax(t[p].r,mid+1,r,L,R);return max(getMax(t[p].l,l,mid,L,mid),getMax(t[p].r,mid+1,r,mid+1,R));}int getSum(int p,int l,int r,int L,int R){int mid = l + r >> 1;if(l == L && r ==  R)return t[p].x;if(R <= mid)return getSum(t[p].l,l,mid,L,R);else if(L > mid)return getSum(t[p].r,mid+1,r,L,R);return getSum(t[p].l,l,mid,L,mid) + getSum(t[p].r,mid+1,r,mid+1,R);}void update(int x,int y){d = y - a[x];a[x] = y;q = pos[x];change(0,1,n);}int qMax(int x,int y){int ans = -9999999;int fx = top[x];int fy = top[y];int l,r;while(fx != fy){if(dep[fx] > dep[fy]){ans = max(ans,getMax(0,1,n,pos[fx],pos[x]));x = fa[fx];fx = top[x];}else{ans = max(ans,getMax(0,1,n,pos[fy],pos[y]));y = fa[fy];fy = top[y];}}if(dep[x] > dep[y])l = pos[y], r = pos[x];elsel = pos[x], r = pos[y];ans = max(ans,getMax(0,1,n,l,r));return ans;}int qSum(int x,int y){int ans = 0;int fx = top[x];int fy = top[y];int l,r;while(fx != fy){if(dep[fx] > dep[fy]){ans += getSum(0,1,n,pos[fx],pos[x]);x = fa[fx];fx = top[x];}else{ans += getSum(0,1,n,pos[fy],pos[y]);y = fa[fy];fy = top[y];}}if(pos[x] > pos[y])l = pos[y], r = pos[x];elsel = pos[x], r = pos[y];ans += getSum(0,1,n,l,r);return ans;}int main(){freopen("1.in","r",stdin);freopen("1.out","w",stdout);cin >> n;for(int i = 0; i < n - 1; i++){scanf("%d%d",&u,&v);build_edge(v,u);build_edge(u,v);}for(int i = 1; i <= n; i++)scanf("%d",&a[i]);memset(vis,0,sizeof(vis));dfs1(1);memset(vis,0,sizeof(vis));dfs2(1);build(0,1,n);cin >> m;char qstr[10];while(m--){scanf("%s",qstr);scanf("%d%d",&x,&y);if(!strcmp(qstr,"CHANGE")){update(x,y);}else if(!strcmp(qstr,"QMAX")){printf("%d\n",qMax(x,y));}else{printf("%d\n",qSum(x,y));}}return 0;}


0 0
原创粉丝点击