题目:
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;
while(!isdigit(c=gc()));T num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs ll INF=1e13;
cs int N=1e5+7;
int n,m;
struct matrix{
ll a[2][2];
matrix(){}
ll *operator[](int of){return a[of];}
cs ll *operator[](int of)cs{return a[of];}
friend matrix operator*(cs matrix &A,cs matrix &B){
matrix C;
C[0][0]=std::min(A[0][0]+B[0][0],A[0][1]+B[1][0]);
C[0][1]=std::min(A[0][0]+B[0][1],A[0][1]+B[1][1]);
C[1][0]=std::min(A[1][0]+B[0][0],A[1][1]+B[1][0]);
C[1][1]=std::min(A[1][0]+B[0][1],A[1][1]+B[1][1]);
return C;
}
};
int nxt[N<<1],to[N<<1],last[N],ecnt;
inline void adde(int u,int v){
nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;
nxt[++ecnt]=last[v],last[v]=ecnt,to[ecnt]=u;
}
int siz[N],son[N];
void pre_dfs(int u,int p){
siz[u]=1;
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]])if(v!=p){
pre_dfs(v,u),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
int cost[N];
namespace GBT{
ll val[N][2];
int rt,son[N][2],fa[N],lsiz[N];
matrix w[N];
int st[N],top;
inline void pushup(int u){
w[u][1][0]=w[u][1][1]=val[u][1];
w[u][0][1]=val[u][0],w[u][0][0]=INF;
w[u]=w[son[u][1]]*w[u]*w[son[u][0]];
}
inline void ins(int u,int v){
ll nt=std::min(w[v][1][0],w[v][1][1]);
ll hv=std::min(std::min(w[v][0][0],w[v][0][1]),nt);
val[u][0]+=nt;val[u][1]+=hv;
}
inline void del(int u,int v){
ll nt=std::min(w[v][1][0],w[v][1][1]);
ll hv=std::min(std::min(w[v][0][0],w[v][0][1]),nt);
val[u][0]-=nt,val[u][1]-=hv;
}
inline int subbuild(int l,int r){
if(l==r){pushup(st[l]);return st[l];}if(l>r)return 0;
int tot=0;for(int re i=l;i<=r;++i)tot+=lsiz[st[i]];
for(int re i=l,now=lsiz[st[i]];i<=r;now+=lsiz[st[++i]])
if(now*2>=tot){
int lc=son[st[i]][0]=subbuild(l,i-1);
int rc=son[st[i]][1]=subbuild(i+1,r);
fa[lc]=fa[rc]=st[i];pushup(st[i]);
return st[i];
}
cerr<<"error 1\n";
assert(0);
}
inline int build(int u){
for(int re p=u;p;p=::son[p])lsiz[p]=siz[p]-siz[::son[p]];
for(int re p=u;p;p=::son[p])
for(int re e=last[p],v=to[e];e;v=to[e=nxt[e]])if(!lsiz[v]){
v=build(v),fa[v]=p;ins(p,v);
}top=0;
for(int re p=u;p;p=::son[p])st[++top]=p,pushup(p);
std::reverse(st+1,st+top+1);return subbuild(1,top);
}
inline bool isrt(int u){return son[fa[u]][1]!=u&&son[fa[u]][0]!=u;}
inline void modify(int u,int tu,ll add){
val[u][!tu]+=add;
while(u){
if(fa[u]&&isrt(u)){
del(fa[u],u);
pushup(u);
ins(fa[u],u);
}
else pushup(u);
u=fa[u];
}
}
inline void query(int u,int tu,int v,int tv){
modify(u,tu,INF);modify(v,tv,INF);
ll ans=std::min(std::min(w[rt][0][0],w[rt][0][1]),std::min(w[rt][1][0],w[rt][1][1]));
cout<<(ans>=INF?-1:ans)<<"\n";
modify(u,tu,-INF);modify(v,tv,-INF);
}
inline void init(){
for(int re i=1;i<=n;++i)val[i][1]=cost[i];
w[0][0][1]=w[0][1][0]=INF;
rt=build(1);
}
}
signed main(){
#ifdef zxyoi
freopen("kingdom.in","r",stdin);
#endif
n=gi(),m=gi();gi();
for(int re i=1;i<=n;++i)cost[i]=gi();
for(int re i=1;i<n;++i)adde(gi(),gi());
pre_dfs(1,0);GBT::init();
while(m--){
int u=gi(),tu=gi(),v=gi(),tv=gi();
GBT::query(u,tu,v,tv);
}
return 0;
}