【BZOJ 1036】[ZJOI2008]树的统计Count 【树链剖分+线段树】
2016-10-27 12:16
531 查看
裸题..
开始的代码有个bug,开始的
这样写为什么会挂啊??
修改方式:
然后build好后在外面单点修改
这里不是很懂啊,我觉得我开始的写法也没错啊qwq
可是不知道为什么过不了。。
宝宝心好痛。
Update:中午回去突然发现..自己又智障了..因为改的val[i]在线段树里的编号不是i..然而因为过了样例所以我居然没有发现这点..zz..真是智障了..
样例这种东西,哪怕算法写错了都能随便过..真是醉了..
开始的代码有个bug,开始的
build()函数是这样写的:
void build(int u,int l,int r){ tr[u].l=l,tr[u].r=r; if(l==r){ tr[u].mx=tr[u].sum=val[l]; return; }; int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(u); }
这样写为什么会挂啊??
修改方式:
if(l==r)return;
然后build好后在外面单点修改
fs(i,1,n)update(1,pos[i],val[i]);
这里不是很懂啊,我觉得我开始的写法也没错啊qwq
可是不知道为什么过不了。。
宝宝心好痛。
Update:中午回去突然发现..自己又智障了..因为改的val[i]在线段树里的编号不是i..然而因为过了样例所以我居然没有发现这点..zz..真是智障了..
样例这种东西,哪怕算法写错了都能随便过..真是醉了..
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<cctype> using namespace std; #define g() getchar() #define d(x) isdigit(x) #define fs(i,s,t) for(int i=(s);i<=(t);i++) char ch;bool sg; template<class T> inline void F(T& x){ for(sg=false,ch=g();!d(ch);ch=='-'?sg=true:1,ch=g()); for(x=0;d(ch);x=x*10+ch-'0',ch=g());sg?x=-x:1; } #define N 30010 int n,Q,head ,eid=0,val ;struct Edge{int to,next;}e[N<<1]; inline void adde(int u,int v){e[++eid].to=v;e[eid].next=head[u];head[u]=eid;} int size ,dep ,fa ; void dfs1(int x){//找重边 size[x]=1; for(int i=head[x];~i;i=e[i].next){ if(e[i].to==fa[x])continue; int v = e[i].to; dep[v] = dep[x]+1;fa[v]=x; dfs1(v); size[x]+=size[v]; } } int tid,pos ,top ; void dfs2(int x,int topx){//连重边成重链 ++tid;pos[x]=tid;top[x]=topx;int k=0;//找重儿子 for(int i=head[x];~i;i=e[i].next) if(dep[e[i].to]>dep[x]&&size[e[i].to]>size[k]) k = e[i].to; if(k==0)return; dfs2(k,topx); for(int i=head[x];~i;i=e[i].next) if(dep[e[i].to]>dep[x]&&e[i].to!=k) dfs2(e[i].to,e[i].to); } struct SegTree{int l,r,mx,sum;}tr[N<<2]; #define ls (u<<1) #define rs (u<<1|1) inline void pushup(int u) { tr[u].mx=max(tr[ls].mx,tr[rs].mx); tr[u].sum=tr[ls].sum+tr[rs].sum; } void build(int u,int l,int r){ tr[u].l=l,tr[u].r=r; if(l==r)return; int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(u); } void update(int u,int x,int k){ if(tr[u].l==tr[u].r){tr[u].mx=tr[u].sum=k;return;} int mid=(tr[u].l+tr[u].r)>>1; if(x<=mid)update(ls,x,k); else update(rs,x,k); pushup(u); } int querymax(int u,int x,int y){ if(x<=tr[u].l&&tr[u].r<=y)return tr[u].mx; int mid=(tr[u].l+tr[u].r)>>1; if(y<=mid)return querymax(ls,x,y); else if(x>mid)return querymax(rs,x,y); else return max(querymax(ls,x,y),querymax(rs,x,y)); } int querysum(int u,int x,int y){ if(x<=tr[u].l&&tr[u].r<=y)return tr[u].sum; int mid=(tr[u].l+tr[u].r)>>1; if(y<=mid)return querysum(ls,x,y); else if(x>mid)return querysum(rs,x,y); else return querysum(ls,x,y)+querysum(rs,x,y); } int askmax(int x,int y){ int ret = -0x7fffffff; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ret = max(ret,querymax(1,pos[top[x]],pos[x])); x = fa[top[x]]; } if(pos[x]>pos[y])swap(x,y); ret=max(ret,querymax(1,pos[x],pos[y])); return ret; } int asksum(int x,int y){ int ret = 0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ret += querysum(1,pos[top[x]],pos[x]); x = fa[top[x]]; } if(pos[x]>pos[y])swap(x,y); ret+=querysum(1,pos[x],pos[y]); return ret; } int main(){ F(n);int a,b;char op[10]; memset(head,-1,sizeof(head)); fs(i,1,n-1){F(a),F(b);adde(a,b);adde(b,a);} fs(i,1,n)F(val[i]); dfs1(1); dfs2(1,1); build(1,1,n); fs(i,1,n)update(1,pos[i],val[i]); F(Q); while(Q--){ scanf("%s%d%d",op,&a,&b); if(*op=='C')val[a]=b,update(1,pos[a],b); else if(*(op+1)=='M')printf("%d\n",askmax(a,b)); else printf("%d\n",asksum(a,b)); } return 0; }
相关文章推荐
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
- bzoj1036[ZJOI2008]树的统计Count 树链剖分+线段树
- BZOJ 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
- 【树链剖分/线段树】BZOJ1036-[ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分 + 线段树)
- 【树链剖分+线段树】BZOJ1036 [ZJOI2008]树的统计Count
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
- BZoj 1036: [ZJOI2008]树的统计Count【树链剖分+线段树--模板题】
- BZOJ-1036: [ZJOI2008]树的统计Count (树链剖分 线段树 单点修改 区间查询 入门题)
- 文章标题 BZOJ 1036 : [ZJOI2008]树的统计Count (树链剖分 + 线段树)
- |BZOJ 1036|树链剖分|线段树|[ZJOI2008]树的统计Count
- bzoj 1036 [ZJOI2008]树的统计Count (树链剖分 + 线段树)
- BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】
- bzoj1036 [ZJOI2008]树的统计Count (树链剖分|Link Cut Tree)
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分裸题)
- [树链剖分] BZOJ1036: [ZJOI2008]树的统计Count
- bzoj 1036: [ZJOI2008]树的统计Count(树链剖分 点权)
- BZOJ 1036 [ZJOI2008]树的统计Count 树链剖分练手题
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)