poj3237 Tree(树链剖分)
来源:互联网 发布:催收数据安全管理制度 编辑:程序博客网 时间:2024/04/30 02:27
边权裸题。negate操作就是区间取相反数。因此为了维护最大值,我们还要维护最小值。
tips:多组数据一定要清零啊。。。懒标记要清零啊。血的教训。
#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define ll long long#define inf 0x7fffffff#define N 10010inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}int n,a[N],p[N],w[N],h[N],dep[N],fa[N],son[N],size[N],top[N],id[N],dfn;struct edge{ int to,next,val;}data[N<<1];struct node{ int mx,mn,neg;}tree[N<<2];void dfs1(int x){ size[x]=1; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(fa[x]==y) continue; fa[y]=x;dep[y]=dep[x]+1;p[i>>1]=y;a[y]=data[i].val; dfs1(y);size[x]+=size[y]; if(size[y]>size[son[x]]) son[x]=y; }}void dfs2(int x,int tp){ id[x]=++dfn;top[x]=tp;w[dfn]=a[x]; if(son[x]) dfs2(son[x],tp); for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); }}inline void pushup(int p){ tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx); tree[p].mn=min(tree[p<<1].mn,tree[p<<1|1].mn);}inline void pushdown(int p){ if(!tree[p].neg) return; tree[p<<1].neg^=1;tree[p<<1|1].neg^=1;tree[p].neg=0; swap(tree[p<<1].mx,tree[p<<1].mn); tree[p<<1].mx=-tree[p<<1].mx;tree[p<<1].mn=-tree[p<<1].mn; swap(tree[p<<1|1].mx,tree[p<<1|1].mn); tree[p<<1|1].mx=-tree[p<<1|1].mx;tree[p<<1|1].mn=-tree[p<<1|1].mn;}void build(int p,int l,int r){ tree[p].neg=0; if(l==r){tree[p].mx=tree[p].mn=w[l];return;} int mid=l+r>>1; build(p<<1,l,mid);build(p<<1|1,mid+1,r); pushup(p);}void negat(int p,int l,int r,int x,int y){ if(x<=l&&r<=y){ tree[p].neg^=1;swap(tree[p].mx,tree[p].mn); tree[p].mx=-tree[p].mx;tree[p].mn=-tree[p].mn; return; } int mid=l+r>>1;pushdown(p); if(x<=mid) negat(p<<1,l,mid,x,y); if(y>mid) negat(p<<1|1,mid+1,r,x,y); pushup(p);}void change(int p,int l,int r,int x,int val){ if(l==r){tree[p].mx=tree[p].mn=val;return;} int mid=l+r>>1;pushdown(p); if(x<=mid) change(p<<1,l,mid,x,val); else change(p<<1|1,mid+1,r,x,val); pushup(p);}int qmax(int p,int l,int r,int x,int y){ if(x<=l&&r<=y){return tree[p].mx;} int mid=l+r>>1,res=-inf;pushdown(p); if(x<=mid) res=max(res,qmax(p<<1,l,mid,x,y)); if(y>mid) res=max(res,qmax(p<<1|1,mid+1,r,x,y)); return res;}void donegate(int x,int y){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); negat(1,1,n,id[top[x]],id[x]); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return; negat(1,1,n,id[x]+1,id[y]);}int domax(int x,int y){ int res=-inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); res=max(res,qmax(1,1,n,id[top[x]],id[x])); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return res; return max(res,qmax(1,1,n,id[x]+1,id[y]));}int main(){// freopen("a.in","r",stdin); int tt=read(); while(tt--){ memset(fa,0,sizeof(fa)); memset(son,0,sizeof(son)); memset(h,0,sizeof(h));dfn=0; n=read(); for(int i=1;i<n;++i){ int x=read(),y=read(),v=read(); data[i<<1].to=y;data[i<<1].next=h[x];h[x]=i<<1;data[i<<1].val=v; data[i<<1|1].to=x;data[i<<1|1].next=h[y];h[y]=i<<1|1;data[i<<1|1].val=v; } dep[1]=1;dfs1(1);dfs2(1,1);build(1,1,n); while(1){ char op[10];scanf("%s",op); if(op[0]=='D') break;int x=read(),y=read(); if(op[0]=='C') change(1,1,n,id[p[x]],y); if(op[0]=='N') donegate(x,y); if(op[0]=='Q') printf("%d\n",domax(x,y)); } } return 0;}
阅读全文
0 0
- 【POJ3237】Tree 树链剖分
- poj3237 Tree 树链剖分
- poj3237 Tree [树链剖分]
- 【POJ3237】Tree(树链剖分)
- 【POJ3237】Tree-树链剖分
- POJ3237 Tree【树链剖分】
- poj3237 Tree(树链剖分)
- poj3237--Tree(树链剖分+线段树)
- 树链剖分+线段树 poj3237 Tree
- poj3237 Tree
- 【poj3237】 Tree
- poj3237 Tree
- POJ3237:Tree
- 【poj3237】Tree
- POJ3237 Tree
- poj3237 Tree
- poj3237 Tree
- poj3237 树链剖分
- 用bochs调试mbr--开始调试啦
- Error:Gradle distribution 'https://services.gradle.org/distributions/gradle-3.3-all.zi
- Problem 1002 cable cable cable-2017 ACM/ICPC Asia Regional Shenyang Online
- ImageLoader的默认配置
- 词法作用域之欺骗词法
- poj3237 Tree(树链剖分)
- 转时间复杂度和空间复杂度详解
- Leetcode :2 Add Two Numbers
- XListView上拉加载下拉刷新
- 第四章 分治策略
- Fast Input
- CSS实现多栏布局的几种方式
- G
- 33muduo_net库源码分析(九)