poj 3237 Tree
题意:给一棵节点数不超过10000的树,有三种操作:
1.询问a,b路径上最大的边权;
2.修改第i条边的边权;
3.将a->b路径上所有边的边权取反。
解法:
spoj375加强版,将点映射到线段树之后,需要用线段树的成段更新来支持操作三,其余的和spoj那题做法一样。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 10010 5 #define lson l,m,n<<1 6 #define rson m+1,r,n<<1|1 7 using namespace std; 8 const int inf=1<<30; 9 struct Edge{ 10 int u,v,len,next; 11 Edge(){} 12 Edge(int _u,int _v,int _len,int _next){ 13 u=_u;v=_v;len=_len;next=_next; 14 } 15 }edge[N<<1],e[N]; 16 int head[N],cnt; 17 int sz[N],son[N],top[N],hash[N],fa[N],dep[N],num; 18 void init(){ 19 memset(head,-1,sizeof(head)); 20 cnt=num=0; 21 } 22 void add(int u,int v,int len){ 23 edge[cnt]=Edge(u,v,len,head[u]);head[u]=cnt++; 24 edge[cnt]=Edge(v,u,len,head[v]);head[v]=cnt++; 25 } 26 void dfs(int u,int d){ 27 sz[u]=1;son[u]=0;dep[u]=d; 28 for(int k=head[u];k!=-1;k=edge[k].next){ 29 int v=edge[k].v; 30 if(v==fa[u])continue; 31 fa[v]=u; 32 dfs(v,d+1); 33 sz[u]+=sz[v]; 34 if(sz[v]>sz[son[u]])son[u]=v; 35 } 36 } 37 void build_tree(int u,int pre){ 38 hash[u]=++num;top[u]=pre; 39 if(son[u])build_tree(son[u],pre); 40 for(int k=head[u];k!=-1;k=edge[k].next){ 41 int v=edge[k].v; 42 if(v!=fa[u]&&v!=son[u])build_tree(v,v); 43 } 44 } 45 struct segtree{ 46 int maxn[N<<2],minn[N<<2]; 47 bool flag[N<<2]; 48 void build(int l,int r,int n){ 49 maxn[n]=-inf; 50 minn[n]=inf; 51 flag[n]=0; 52 if(l==r)return; 53 int m=(l+r)>>1; 54 build(lson); 55 build(rson); 56 } 57 void pushup(int n){ 58 maxn[n]=max(maxn[n<<1],maxn[n<<1|1]); 59 minn[n]=min(minn[n<<1],minn[n<<1|1]); 60 } 61 void pushdown(int n){ 62 if(flag[n]){ 63 flag[n<<1]^=1; 64 flag[n<<1|1]^=1; 65 int mx,mn; 66 mx=maxn[n<<1],mn=minn[n<<1]; 67 maxn[n<<1]=-mn;minn[n<<1]=-mx; 68 mx=maxn[n<<1|1],mn=minn[n<<1|1]; 69 maxn[n<<1|1]=-mn;minn[n<<1|1]=-mx; 70 flag[n]=0; 71 } 72 } 73 void update_1(int ll,int rr,int l,int r,int n){ 74 if(ll==l&&rr==r){ 75 flag[n]^=1; 76 int mx=maxn[n],mn=minn[n]; 77 maxn[n]=-mn; 78 minn[n]=-mx; 79 return; 80 } 81 pushdown(n); 82 int m=(l+r)>>1; 83 if(rr<=m)update_1(ll,rr,lson); 84 else if(ll>m)update_1(ll,rr,rson); 85 else update_1(ll,m,lson),update_1(m+1,rr,rson); 86 pushup(n); 87 } 88 void update_2(int nn,int x,int l,int r,int n){ 89 if(l==r){ 90 flag[n]=0; 91 maxn[n]=minn[n]=x; 92 return; 93 } 94 int m=(l+r)>>1; 95 pushdown(n); 96 if(nn<=m)update_2(nn,x,lson); 97 else update_2(nn,x,rson); 98 pushup(n); 99 } 100 int query(int ll,int rr,int l,int r,int n){ 101 if(ll==l&&rr==r)return maxn[n]; 102 int m=(l+r)>>1; 103 pushdown(n); 104 if(rr<=m)return query(ll,rr,lson); 105 else if(ll>m)return query(ll,rr,rson); 106 else return max(query(ll,m,lson),query(m+1,rr,rson)); 107 } 108 }seg; 109 int Query(int a,int b,int n){ 110 int ta=top[a],tb=top[b],ans=-inf; 111 while(ta!=tb){ 112 if(dep[ta]<dep[tb]){ 113 swap(ta,tb);swap(a,b); 114 } 115 ans=max(ans,seg.query(hash[ta],hash[a],1,n,1)); 116 a=fa[ta];ta=top[a]; 117 } 118 if(a==b)return ans; 119 if(dep[a]>dep[b])swap(a,b); 120 return max(ans,seg.query(hash[son[a]],hash[b],1,n,1)); 121 } 122 void Update(int a,int b,int n){ 123 int ta=top[a],tb=top[b]; 124 while(ta!=tb){ 125 if(dep[ta]<dep[tb]){ 126 swap(ta,tb);swap(a,b); 127 } 128 seg.update_1(hash[ta],hash[a],1,n,1); 129 a=fa[ta];ta=top[a]; 130 } 131 if(a==b)return; 132 if(dep[a]>dep[b])swap(a,b); 133 seg.update_1(hash[son[a]],hash[b],1,n,1); 134 } 135 136 int main(){ 137 int t,n,a,b; 138 char op[10]; 139 scanf("%d",&t); 140 while(t--){ 141 init(); 142 scanf("%d",&n); 143 for(int i=1;i<n;i++){ 144 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].len); 145 add(e[i].u,e[i].v,e[i].len); 146 } 147 dfs(1,1); 148 build_tree(1,1); 149 seg.build(1,n,1); 150 for(int i=1;i<n;i++){ 151 if(dep[e[i].u]>dep[e[i].v]) 152 swap(e[i].u,e[i].v); 153 seg.update_2(hash[e[i].v],e[i].len,1,n,1); 154 } 155 while(scanf("%s",op)&&op[0]!='D'){ 156 scanf("%d%d",&a,&b); 157 if(op[0]=='C'){ 158 seg.update_2(hash[e[a].v],b,1,n,1); 159 }else if(op[0]=='N'){ 160 Update(a,b,n); 161 }else if(op[0]=='Q'){ 162 int ans=Query(a,b,n); 163 printf("%d\n",ans); 164 } 165 } 166 } 167 return 0; 168 }