BZOJ 1984 月下“毛景树” 树链剖分

来源:互联网 发布:c语言逻辑运算符 编辑:程序博客网 时间:2024/04/29 04:01

题目大意:给定一棵树,边上有边权,提供一堆乱七八糟的操作(0.0),多次询问两点之间边权最大值

将每条边的边权放在边下面的点上,然后按照点权处理就行了。注意两个点的LCA的点权不能被算进路径中去

尼玛UBUNTU奇葩系统……我不写返回值居然直接把re给我返回回去了 然后咋拍都过…… 交上去就WA…… 我跪了

再也不敢不写-Wall了……

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 100100using namespace std;struct Segtree{Segtree *ls,*rs;int change_mark,add_mark,max_num;void Add(int x);void Change(int x);void* operator new(size_t size);}*tree,mempool[M<<1],*C=mempool;struct abcd{int to,f,next;}table[M<<1];int head[M],tot=1;int n;int fa[M],son[M],dpt[M],size[M];int pos[M],top[M],f[M],posf[M],cnt;void Segtree :: Add(int x){add_mark+=x;max_num+=x;}void Segtree :: Change(int x){add_mark=0;change_mark=x;max_num=x;}void* Segtree :: operator new(size_t size){C->change_mark=-1;return C++;}void Build_Tree(Segtree*&p,int x,int y){int mid=x+y>>1;p=new Segtree;if(x==y){p->max_num=posf[mid];return ;}Build_Tree(p->ls,x,mid);Build_Tree(p->rs,mid+1,y);p->max_num=max(p->ls->max_num,p->rs->max_num);}void Change(Segtree*p,int x,int y,int z,int v){int mid=x+y>>1;if(x==y){p->max_num=v;return ;}if(~p->change_mark){p->ls->Change(p->change_mark);p->rs->Change(p->change_mark);p->change_mark=-1;}if(p->add_mark){p->ls->Add(p->add_mark);p->rs->Add(p->add_mark);p->add_mark=0;}if(z<=mid) Change(p->ls,x,mid,z,v);else Change(p->rs,mid+1,y,z,v);p->max_num=max(p->ls->max_num,p->rs->max_num);}void Change(Segtree*p,int x,int y,int l,int r,int v){int mid=x+y>>1;if(x==l&&y==r){p->Change(v);return ;}if(~p->change_mark){p->ls->Change(p->change_mark);p->rs->Change(p->change_mark);p->change_mark=-1;}if(p->add_mark){p->ls->Add(p->add_mark);p->rs->Add(p->add_mark);p->add_mark=0;}if(r<=mid) Change(p->ls,x,mid,l,r,v);else if(l>mid) Change(p->rs,mid+1,y,l,r,v);else Change(p->ls,x,mid,l,mid,v),Change(p->rs,mid+1,y,mid+1,r,v);p->max_num=max(p->ls->max_num,p->rs->max_num);}void Add(Segtree*p,int x,int y,int l,int r,int v){int mid=x+y>>1;if(x==l&&y==r){p->Add(v);return ;}if(~p->change_mark){p->ls->Change(p->change_mark);p->rs->Change(p->change_mark);p->change_mark=-1;}if(p->add_mark){p->ls->Add(p->add_mark);p->rs->Add(p->add_mark);p->add_mark=0;}if(r<=mid) Add(p->ls,x,mid,l,r,v);else if(l>mid) Add(p->rs,mid+1,y,l,r,v);else Add(p->ls,x,mid,l,mid,v),Add(p->rs,mid+1,y,mid+1,r,v);p->max_num=max(p->ls->max_num,p->rs->max_num);}int Get_Ans(Segtree*p,int x,int y,int l,int r){int mid=x+y>>1;if(x==l&&y==r)return p->max_num;if(~p->change_mark){p->ls->Change(p->change_mark);p->rs->Change(p->change_mark);p->change_mark=-1;}if(p->add_mark){p->ls->Add(p->add_mark);p->rs->Add(p->add_mark);p->add_mark=0;}if(r<=mid) return Get_Ans(p->ls,x,mid,l,r);if(l>mid) return Get_Ans(p->rs,mid+1,y,l,r);return max( Get_Ans(p->ls,x,mid,l,mid) , Get_Ans(p->rs,mid+1,y,mid+1,r) );}void Add(int x,int y,int z){table[++tot].to=y;table[tot].f=z;table[tot].next=head[x];head[x]=tot;}void DFS1(int x){int i;dpt[x]=dpt[fa[x]]+1;size[x]=1;for(i=head[x];i;i=table[i].next){if(table[i].to==fa[x])continue;fa[table[i].to]=x;f[table[i].to]=table[i].f;DFS1(table[i].to);size[x]+=size[table[i].to];if(size[table[i].to]>size[son[x]])son[x]=table[i].to;}}void DFS2(int x){int i;if(son[fa[x]]==x)top[x]=top[fa[x]];elsetop[x]=x;posf[pos[x]=++cnt]=f[x];if(son[x]) DFS2(son[x]);for(i=head[x];i;i=table[i].next){if(table[i].to==fa[x]||table[i].to==son[x])continue;DFS2(table[i].to);}}int Query(int x,int y){int re=-2147483647,fx=top[x],fy=top[y];while(fx!=fy){if(dpt[fx]<dpt[fy])swap(x,y),swap(fx,fy);re=max(re, Get_Ans(tree,1,n,pos[fx],pos[x]) );fx=top[x=fa[fx]];}if(x==y) return re;if(dpt[x]<dpt[y])swap(x,y);re=max(re, Get_Ans(tree,1,n,pos[y]+1,pos[x]) );return re;}void Change(int x,int y,int z){int fx=top[x],fy=top[y];while(fx!=fy){if(dpt[fx]<dpt[fy])swap(x,y),swap(fx,fy);Change(tree,1,n,pos[fx],pos[x],z);fx=top[x=fa[fx]];}if(x==y) return ;if(dpt[x]<dpt[y])swap(x,y);Change(tree,1,n,pos[y]+1,pos[x],z);}void _Add(int x,int y,int z){int fx=top[x],fy=top[y];while(fx!=fy){if(dpt[fx]<dpt[fy])swap(x,y),swap(fx,fy);Add(tree,1,n,pos[fx],pos[x],z);fx=top[x=fa[fx]];}if(x==y) return ;if(dpt[x]<dpt[y])swap(x,y);Add(tree,1,n,pos[y]+1,pos[x],z);}int main(){#ifdef PoPoQQQfreopen("1984.in","r",stdin);freopen("1984.out","w",stdout);#endifint i,x,y,z;char p[20];cin>>n;for(i=1;i<n;i++){scanf("%d%d%d",&x,&y,&z);Add(x,y,z);Add(y,x,z);}DFS1(1);DFS2(1);Build_Tree(tree,1,n);while(1){scanf("%s",p);switch(p[1]){case 'a':scanf("%d%d",&x,&y);printf("%d\n", Query(x,y) );break;case 'h':int temp;scanf("%d%d",&temp,&z);x=table[temp<<1].to;y=table[temp<<1|1].to;if(dpt[x]<dpt[y])swap(x,y);Change(tree,1,n,pos[x],z);break;case 'o':scanf("%d%d%d",&x,&y,&z);Change(x,y,z);break;case 'd':scanf("%d%d%d",&x,&y,&z);_Add(x,y,z);break;case 't':return 0;}}}


0 0