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
- BZOJ 1984 月下“毛景树” 树链剖分
- bzoj 1984: 月下“毛景树”
- bzoj 1984: 月下“毛景树” 线段树+树链剖分
- 1984: 月下“毛景树”
- 【BZOJ1984】月下“毛景树”-树链剖分
- [bzoj1984]月下“毛景树” 树链剖分
- 【bzoj1984】【坑】月下“毛景树” 树链剖分
- [BZOJ1984]月下“毛景树”(树链剖分)
- bzoj-1502 月下柠檬树
- 月下“毛景树”
- 【BZOJ】【P1984】【月下“毛景树”】【题解】【链剖线段树】
- bzoj 1502: [NOI2005]月下柠檬树
- bzoj1984 月下“毛景树”树链剖分 线段树
- bzoj1984 月下“毛景树”(边权的树链剖分)
- BZOJ1984月下“毛景树”
- BZOJ1984: 月下“毛景树”
- BZOJ1984: 月下“毛景树”
- BZOJ1984 月下“毛景树”
- 新入行程序员须知的8件事
- 双11不造买啥,来看看这款智能行李箱吧
- 19. JAVA 网络编程 Part 1 (IP与InetAddress类、URL与URLConnection类、URLEncoder与URLDecoder类、TCP&UDP)---- 学习笔记
- zTree -- jQuery 树插件
- 如何评价用户忠诚度
- BZOJ 1984 月下“毛景树” 树链剖分
- struts2 jar包详解
- IOS 7 改变状态栏颜色
- 读取本地图片并预览(转载)
- ORACLE profile系列4 --CREATE PROFILE
- mac下配置ndk和sdk环境变量
- UML画图总结
- PHP草根论之设计 模式-组合模式
- mac os 上的apt-get的alternative command