边权【spoj 375】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10010;
struct Edge{
int to,next;
}edge[maxn*2];
int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;
void init(){
pos=0;tot=0;
memset(head,-1,sizeof head);
memset(son,-1,sizeof son);
}
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs_1(int u,int pre,int d){
deep[u]=d;
fa[u]=pre;
num[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v!=pre){
dfs_1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]]){
son[u]=v;
}
}
}
}
void dfs_2(int u,int sp){
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)return;
dfs_2(son[u],sp);
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u]&&v!=son[u]){
dfs_2(v,v);
}
}
}
struct node{
int l,r;
int Max;
}ST[maxn<<2];
void build(int i,int l,int r){
ST[i].l=l;
ST[i].r=r;
ST[i].Max=0;
if(l==r)return;
int md=(l+r)/2;
build(i<<1,l,md);
build((i<<1)|1,md+1,r);
}
void push_up(int i){
ST[i].Max=max(ST[i<<1].Max,ST[(i<<1)|1].Max);
}
void update(int i,int k,int val){
if(ST[i].l==ST[i].r){
ST[i].Max=val;
return;
}
int md=(ST[i].l+ST[i].r)/2;
if(k<=md)update(i<<1,k,val);
else update((i<<1)|1,k,val);
push_up(i);
}
int qry(int i,int l,int r){
if(ST[i].l == l && ST[i].r == r){
return ST[i].Max;
}
int md=(ST[i].l+ST[i].r)/2;
if(r<=md)return qry(i<<1,l,r);
else if(l>md)return qry((i<<1)|1,l,r);
return max(qry(i<<1,l,md),qry((i<<1)|1,md+1,r));
}
int find(int u,int v){
int f1=top[u],f2=top[v];
int tmp=0;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
tmp=max(tmp,qry(1,p[f1],p[u]));
u=fa[f1];f1=top[u];
}
if(u==v)return tmp;
if(deep[u]>deep[v])swap(u,v);
return max(tmp,qry(1,p[son[u]],p[v]));
}
int e[maxn][3];
int main(){
//freopen("in.txt","r",stdin);
int t,n;
for(scanf("%d",&t);t--;){
init();
scanf("%d",&n);
for(int i=0;i<n-1;i++){
scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
addedge(e[i][0],e[i][1]);
addedge(e[i][1],e[i][0]);
}
dfs_1(1,0,0);
dfs_2(1,1);
build(1,0,pos-1);
for(int i=0;i<n-1;i++){
if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
update(1,p[e[i][1]],e[i][2]);
}
char op[110];
int u,v;
while(1){
scanf("%s",op);
if (op[0]=='D')break;
scanf("%d%d",&u,&v);
if(op[0]=='Q')printf("%d\n",find(u,v));
else update(1,p[e[u-1][1]],v);
}
}
}
边权【poj2763】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (p<<1)
#define rs (p<<1|1)
#define push_up; T[p].sum=T[ls].sum+T[rs].sum;
using namespace std;
typedef long long ll;
const int maxn = 100011;
struct Edge{
int to,next;
}edge[maxn<<1];
int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;
int e[maxn][3];
struct node{
int l,r;
ll sum;
}T[maxn<<2];
void build(int p,int l,int r){
T[p].l=l,T[p].r=r;
T[p].sum=0;
if(l==r)return;
int md=(l+r)>>1;
build(ls,l,md);
build(rs,md+1,r);
}
void update(int p,int k,int val){
if(T[p].l==T[p].r){
T[p].sum=val;
return;
}
int md=(T[p].l+T[p].r)>>1;
if(k<=md)update(ls,k,val);
else update(rs,k,val);
push_up;
}
ll qry(int p,int l,int r){
//cout<<l<<' '<<r<<endl;
//cout<<T[p].l<<' '<<md<<' '<<T[p].r<<endl<<endl;;
if(T[p].l>=l&&T[p].r<=r)return T[p].sum;
int md=(T[p].l+T[p].r)>>1;
if(r<=md)return qry(ls,l,r);
else if(l>md)return qry(rs,l,r);
return qry(ls,l,md)+qry(rs,md+1,r);
}
void init(){
pos=0;tot=0;
memset(head,-1,sizeof head);
memset(son,-1,sizeof son);
}
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs_1(int u,int pre,int d){
fa[u]=pre;
deep[u]=d;
num[u]=1;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=pre){
dfs_1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]]){
son[u]=v;
}
}
}
}
void dfs_2(int u,int sp){
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)return;
dfs_2(son[u],sp);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u]&&v!=son[u]){
dfs_2(v,v);
}
}
}
ll find(int u,int v){
int f1=top[u],f2=top[v];
ll tmp=0;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
tmp+=qry(1,p[f1],p[u]);
u=fa[f1];f1=top[u];
}
if(u==v)return tmp;
if(deep[u]>deep[v])swap(u,v);
tmp+=qry(1,p[son[u]],p[v]);
return tmp;
}
int main(){
init();
int n,q,cnt,op,i,w;
scanf("%d%d%d",&n,&q,&cnt);
for(int i=1;i<=n-1;i++){
scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
addedge(e[i][0],e[i][1]);
addedge(e[i][1],e[i][0]);
}
dfs_1(1,0,0);
dfs_2(1,1);
build(1,0,pos-1);
for(int i=1;i<=n-1;i++){
if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
update(1,p[e[i][1]],e[i][2]);
}
while(q--){
scanf("%d%d",&op,&i);
if(op){
scanf("%d",&w);
update(1,p[e[i][1]],w);
}else{
printf("%lld\n",find(cnt,i));
cnt=i;
}
}
}
边权【POJ 3237】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ls (p<<1)
#define rs ((p<<1)|1)
using namespace std;
typedef long long ll;
const int maxn = 10010;
struct Edge{
int to,next;
}edge[maxn*2];
int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;
void init(){
pos=0;tot=0;
memset(head,-1,sizeof head);
memset(son,-1,sizeof son);
}
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs_1(int u,int pre,int d){
deep[u]=d;
fa[u]=pre;
num[u]=1;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=pre){
dfs_1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[son[u]]<num[v]){
son[u]=v;
}
}
}
}
void dfs_2(int u,int tp){
top[u]=tp;
p[u]=++pos;
fp[p[u]]=u;
if(-1==son[u])return;
dfs_2(son[u],tp);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=son[u]&&v!=fa[u]){
dfs_2(v,v);
}
}
}
struct node{
int l,r,mx,mi,lazy;
}T[maxn<<2];
void re(int p){
T[p].lazy^=1;swap(T[p].mx,T[p].mi);
T[p].mx*=-1;T[p].mi*=-1;
}
void push_down(int p){
if(T[p].lazy==1)re(ls),re(rs);
T[p].lazy=0;
}
void push_up(int p){
T[p].mx=max(T[ls].mx,T[rs].mx);
T[p].mi=min(T[ls].mi,T[rs].mi);
}
void update(int p,int k,int val){
if(T[p].l==T[p].r){
T[p].mx=val;
T[p].mi=val;
T[p].lazy=0;
return;
}
push_down(p);
int md=(T[p].l+T[p].r)>>1;
if(k<=md)update(ls,k,val);
else update(rs,k,val);
push_up(p);
}
void update_2(int p,int l,int r){
if(T[p].l>=l&&T[p].r<=r){
re(p);
return;
}
push_down(p);
int md = (T[p].l+T[p].r)>>1;
if(l<=md)update_2(ls,l,r);
if(r>md)update_2(rs,l,r);
push_up(p);
}
int qry(int p,int l,int r){
if(T[p].l>=l&&T[p].r<=r){
return T[p].mx;
}
push_down(p);
int tmp=-1e16;
int md = (T[p].l+T[p].r)>>1;
if(l<=md)tmp=max(tmp,qry(ls,l,r));
if(r>md)tmp=max(tmp,qry(rs,l,r));
push_up(p);
return tmp;
}
void build(int p,int l,int r){
T[p].l=l,T[p].r=r;
T[p].lazy=0;
T[p].mx=0,T[p].mi=0;
if(l==r)return;
int md=(l+r)>>1;
if(l<=md)build(ls,l,md);
if(r>md)build(rs,md+1,r);
}
int find(int u,int v){
int f1=top[u],f2=top[v];
int tmp=-1e16;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
tmp=max(tmp,qry(1,p[f1],p[u]));
u=fa[f1];f1=top[u];
}
if(u==v)return tmp;
if(deep[u]>deep[v])swap(u,v);
tmp=max(tmp,qry(1,p[son[u]],p[v]));
return tmp;
}
void cg(int u,int v){
int f1=top[u],f2=top[v];
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
update_2(1,p[f1],p[u]);
u=fa[f1];f1=top[u];
}
if(u==v)return;
if(deep[u]>deep[v])swap(u,v);
update_2(1,p[son[u]],p[v]);
}
int e[maxn][3];
int main(){
int t,n,m;
for(scanf("%d",&t);t--;){
init();
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
addedge(e[i][0],e[i][1]);
addedge(e[i][1],e[i][0]);
}
dfs_1(1,0,0);
dfs_2(1,1);
build(1,1,pos);//cout<<23333<<endl;
for(int i=1;i<=n-1;i++){
if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
update(1,p[e[i][1]],e[i][2]);
}
char op[50];
int u,v;
while(1){
scanf("%s",op);
if(op[0]=='D')break;
scanf("%d%d",&u,&v);
if(op[0]=='Q')printf("%d\n",find(u,v));
if(op[0]=='C')update(1,p[e[u][1]],v);
if(op[0]=='N')cg(u,v);
}
}
return 0;
}
点权【HDU 3966】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 50050;
struct Edge{
ll to,next;
}edge[maxn*2];
ll head[maxn],tot;
ll top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
ll pos;
ll a[maxn];
ll n;
void init(){
pos=0;tot=0;
memset(head,-1,(n+5)*sizeof(ll));
memset(son,-1,(n+5)*sizeof(ll));
}
void addedge(ll u,ll v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs_1(ll u,ll pre,ll d){
deep[u]=d;
fa[u]=pre;
num[u]=1;
for(ll i=head[u];i!=-1;i=edge[i].next){
ll v=edge[i].to;
if(v!=pre){
dfs_1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]]){
son[u]=v;
}
}
}
}
void dfs_2(ll u,ll sp){
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)return;
dfs_2(son[u],sp);
for(ll i=head[u];i!=-1;i=edge[i].next){
ll v=edge[i].to;
if(v!=fa[u]&&v!=son[u]){
dfs_2(v,v);
}
}
}
struct node{
ll l,r,lazy;
ll sum;
}ST[maxn<<2];
void build(ll i,ll l,ll r){
ST[i].l=l;
ST[i].r=r;
ST[i].sum=0;
ST[i].lazy=0;
if(l==r)return;
ll md=(l+r)/2;
build(i<<1,l,md);
build((i<<1)|1,md+1,r);
}
void push_up(ll i){
ST[i].sum=ST[i<<1].sum+ST[(i<<1)|1].sum;
}
void push_down(ll i){
ST[i<<1].lazy+=ST[i].lazy;
ST[(i<<1)|1].lazy+=ST[i].lazy;
ST[i<<1].sum+=(ST[i<<1].r-ST[i<<1].l+1)*ST[i].lazy;
ST[(i<<1)|1].sum+=(ST[(i<<1)|1].r-ST[(i<<1)|1].l+1)*ST[i].lazy;
ST[i].lazy=0;
}
void update(ll i,ll l,ll r,ll val){
if(ST[i].l>=l&&ST[i].r<=r){
ST[i].lazy+=val;
ST[i].sum+=(ST[i].r-ST[i].l+1)*val;
return;
}
push_down(i);
ll md=(ST[i].l+ST[i].r)/2;
if(l<=md)update(i<<1,l,r,val);
if(r>md) update((i<<1)|1,l,r,val);
push_up(i);
}
ll qry(ll i,ll l,ll r){
if(ST[i].l == l && ST[i].r == r){
return ST[i].sum;
}
if(ST[i].lazy){
push_down(i);
push_up(i);
}
ll md=(ST[i].l+ST[i].r)/2;
if(r<=md)return qry(i<<1,l,r);
else if(l>md)return qry((i<<1)|1,l,r);
return qry(i<<1,l,md)+qry((i<<1)|1,md+1,r);
}
int up(ll u,ll v,ll val){
int f1=top[u],f2=top[v];
int tmp=0;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
update(1,p[f1],p[u],val);
u=fa[f1];f1=top[u];
}
if(u==v)update(1,p[u],p[u],val);
else{
if(deep[u]>deep[v])swap(u,v);
update(1,p[u],p[v],val);
}
}
ll e[maxn][3];
int main(){
//freopen("in.txt","r",stdin);
ll t,m,q;
while(~scanf("%lld%lld%lld",&n,&m,&q)){
init();
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(ll i=0;i<n-1;i++){
scanf("%lld%lld",&e[i][0],&e[i][1]);
addedge(e[i][0],e[i][1]);
addedge(e[i][1],e[i][0]);
}
dfs_1(1,0,0);
dfs_2(1,1);
build(1,0,pos-1);
for(ll i=1;i<=n;i++){
update(1,p[i],p[i],a[i]);
}
char op[110];
ll u,v,val;
while(q--){
scanf("%s",op);
if (op[0]=='Q'){
scanf("%lld",&u);
printf("%lld\n",qry(1,p[u],p[u]));
}
else {
scanf("%lld%lld%lld",&u,&v,&val);
if(op[0]=='D')val=-val;
up(u,v,val);
}
}
}
}
点权【bzoj2243】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ls (p<<1)
#define rs ((p<<1)|1)
using namespace std;
typedef long long ll;
const ll maxn = 100050;
struct Edge{
ll to,next;
}edge[maxn*2];
int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos,a[maxn],n,q;
void init(){
pos=0;tot=0;
memset(head,-1,(n+5)*sizeof(int));
memset(son,-1,(n+5)*sizeof(int));
}
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs_1(int u,int pre,int d){
deep[u]=d;
fa[u]=pre;
num[u]=1;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=pre){
dfs_1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]]){
son[u]=v;
}
}
}
}
void dfs_2(int u,int tp){
top[u]=tp;
p[u]=++pos;
fp[p[u]]=u;
if(-1==son[u])return;
dfs_2(son[u],tp);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u]&&v!=son[u]){
dfs_2(v,v);
}
}
}
struct node{
int l,r,lc,rc;
int num,lazy;
}T[maxn<<2];
void push_up(int p){
T[p].num=T[ls].num+T[rs].num-(T[ls].rc==T[rs].lc);
T[p].lc=T[ls].lc;T[p].rc=T[rs].rc;
}
void push_down(int p){
if(~T[p].lazy){
T[ls].lc=T[ls].rc=T[ls].lazy=T[p].lazy;
T[rs].lc=T[rs].rc=T[rs].lazy=T[p].lazy;
T[ls].num=1;T[rs].num=1;
}
T[p].lazy=-1;
}
void build(int p,int l,int r){
T[p].l=l,T[p].r=r,T[p].lazy=-1;
if(l==r){
T[p].lc=T[p].rc=T[p].lazy=a[fp[l]];
T[p].num=1;
return;
}
int md=(l+r)>>1;
build(ls,l,md);
build(rs,md+1,r);
push_up(p);
}
void update(int p,int l,int r,int val){
if(T[p].l==l&&T[p].r==r){
T[p].lc=T[p].rc=T[p].lazy=val;
T[p].num=1;
return;
}
push_down(p);
int md=(T[p].l+T[p].r)>>1;
if(r<=md)update(ls,l,r,val);
else if(l>md)update(rs,l,r,val);
else{
update(ls,l,md,val);
update(rs,md+1,r,val);
}
push_up(p);
}
node qry(int p,int l,int r){
if(T[p].l==l&&T[p].r==r){
return T[p];
}
node res,tmp;
push_down(p);
int md=(T[p].l+T[p].r)>>1;
if(r<=md)return qry(ls,l,r);
else if(l>md)return qry(rs,l,r);
else{
res=qry(ls,l,md);
tmp=qry(rs,md+1,r);
res.num+=tmp.num-(res.rc==tmp.lc);
res.rc=tmp.rc;
return res;
}
}
void cg(int u,int v,int val){
int f1=top[u],f2=top[v];
int tmp=0;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
update(1,p[f1],p[u],val);
u=fa[f1];f1=top[u];
}
if(u==v)update(1,p[u],p[u],val);
else{
if(deep[u]>deep[v])swap(u,v);
update(1,p[u],p[v],val);
}
}
//
// if(deep[u]>deep[v])swap(u,v);
// tmp=max(tmp,qry(1,p[son[u]],p[v]));
// return tmp;
int find(int u,int v){
int f1=top[u],f2=top[v];
node tmp;
int res=0,uc=-1,vc=-1;
while(f1!=f2){
if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2),swap(uc,vc);
tmp=qry(1,p[f1],p[u]);
res+=tmp.num-(uc==tmp.rc);
uc=tmp.lc;
u=fa[f1];f1=top[u];
}
if(u!=v)if(deep[u]>deep[v])swap(u,v),swap(uc,vc);
tmp=qry(1,p[u],p[v]);
res+=tmp.num-(uc==tmp.lc)-(vc==tmp.rc);
return res;
}
ll e[maxn][3];
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&q);
init();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++){
scanf("%d%d",&e[i][0],&e[i][1]);
addedge(e[i][0],e[i][1]);
addedge(e[i][1],e[i][0]);
}
dfs_1(1,0,0);
dfs_2(1,1);
build(1,1,pos);
char op[10];
int u,v,w;
while(q--){
scanf("%s%d%d",op,&u,&v);
//cout<<op<<endl;
if(op[0]=='Q')printf("%d\n",find(u,v));
else {
scanf("%d",&w);
cg(u,v,w);
}
}
}