可以直接套动态dp,但因为它询问之间相互独立,所以可以直接倍增记x转移到fa[x]的矩阵

 #include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
const int maxn=1e5+;
const ll inf=1e17; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,M,p[maxn];
int eg[maxn*][],egh[maxn],ect,fa[maxn][],dep[maxn];
ll f[maxn][];
struct Mat{
int n,m;ll a[][];
Mat(int a0=,int a1=,ll a2=,ll a3=,ll a4=,ll a5=){
n=a0,m=a1;a[][]=a2,a[][]=a3,a[][]=a4,a[][]=a5;
}
}trans[maxn][]; inline Mat operator * (Mat a,Mat b){
Mat re;
re.n=a.n,re.m=b.m;
for(int i=;i<=re.n;i++){
for(int j=;j<=re.m;j++){
re.a[i][j]=inf;
for(int k=;k<=a.m;k++){
re.a[i][j]=min(re.a[i][j],a.a[i][k]+b.a[k][j]);
}
}
}return re;
} inline void adeg(int a,int b){
eg[++ect][]=b,eg[ect][]=egh[a],egh[a]=ect;
} void dfs1(int x){
f[x][]=,f[x][]=p[x];
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
fa[b][]=x,dep[b]=dep[x]+;
dfs1(b);
f[x][]+=f[b][],f[x][]+=min(f[b][],f[b][]);
}
} void dfs2(int x){
if(fa[x][]){
ll s0,s1;
s0=f[fa[x][]][]-f[x][];
s1=f[fa[x][]][]-min(f[x][],f[x][]);
trans[x][]=Mat(,,inf,s1,s0,s1);
for(int i=;fa[x][i]&&fa[fa[x][i]][i];i++){
fa[x][i+]=fa[fa[x][i]][i];
trans[x][i+]=trans[x][i]*trans[fa[x][i]][i];
}
}
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];if(b==fa[x][]) continue;
dfs2(b);
}
} inline ll update(int x,int y,Mat &fx,Mat &fy){
for(int i=log2(dep[x]-dep[y]);i>=&&dep[x]!=dep[y];i--){
if(dep[fa[x][i]]>=dep[y])
fx=fx*trans[x][i],x=fa[x][i];
}
int lca;Mat fl;
if(x==y){
lca=y;fl=fx;
if(fy.a[][]==inf) fl.a[][]=inf;
else if(fy.a[][]==inf) fl.a[][]=inf;
}else{
for(int i=log2(dep[x]);i>=;i--){
if(fa[x][i]!=fa[y][i]){
fx=fx*trans[x][i],fy=fy*trans[y][i];
x=fa[x][i],y=fa[y][i];
}
}
lca=fa[x][];
// printf("~%d %d %d %d %d %d\n",x,fx.a[1][1],fx.a[1][2],y,fy.a[1][1],fy.a[1][2]);
ll a0=f[lca][]-f[x][]-f[y][]+fx.a[][]+fy.a[][];
ll a1=f[lca][]-min(f[x][],f[x][])-min(f[y][],f[y][])+min(fx.a[][],fx.a[][])+min(fy.a[][],fy.a[][]);
fl=Mat(,,a0,a1,,);
}
for(int i=log2(dep[lca]);i>=;i--){
if(fa[lca][i]){
fl=fl*trans[lca][i];
lca=fa[lca][i];
}
}
return min(fl.a[][],fl.a[][]);
} int main(){
// freopen("testdata.in","r",stdin);
int i,j,k;
N=rd(),M=rd();rd();
for(i=;i<=N;i++) p[i]=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
dep[]=;dfs1();dfs2();
for(i=;i<=M;i++){
int a=rd(),x=rd(),b=rd(),y=rd();
if(dep[a]<dep[b]) swap(a,b),swap(x,y);
if(fa[a][]==b&&!x&&!y){
printf("-1\n");continue;
}
Mat fx,fy;
if(x) fx=Mat(,,inf,f[a][],,);
else fx=Mat(,,f[a][],inf,,);
if(y) fy=Mat(,,inf,f[b][],,);
else fy=Mat(,,f[b][],inf,,);
printf("%lld\n",update(a,b,fx,fy));
}
return ;
}

luogu5024 [NOIp2018]保卫王国 (动态dp)的更多相关文章

  1. BZOJ 5466: [Noip2018]保卫王国 动态DP

    Code: // luogu-judger-enable-o2 #include<bits/stdc++.h> #define ll long long #define lson (now ...

  2. JZOJ5966. [NOIP2018TGD2T3] 保卫王国 (动态DP做法)

    题目大意 这还不是人尽皆知? 有一棵树, 每个节点放军队的代价是\(a_i\), 一条边连接的两个点至少有一个要放军队, 还有\(q\)次询问, 每次规定其中的两个一定需要/不可放置军队, 问这样修改 ...

  3. 【NOIP2018】保卫王国 动态dp

    此题场上打了一个正确的$44pts$,接着看错题疯狂$rush$“正确”的$44pts$,后来没$rush$完没将之前的代码$copy$回去,直接变零分了..... 这一题我们显然有一种$O(nm)$ ...

  4. luoguP5024 保卫王国 动态dp

    题目大意: emmmmm 题解: QAQ #include <cstdio> #include <cstring> #include <iostream> usin ...

  5. LuoguP5024 保卫王国(动态DP,LCT)

    最小权覆盖集 = 全集 - 最大权独立集 强制取点.不取点可以使用把权值改成正无穷或负无穷实现 接下来就是经典的"动态最大权独立集"了 O(nlogn). 这不是我说的,是immo ...

  6. P5024 保卫王国(动态dp/整体dp/倍增dp)

    做法(倍增) 最好写的一种 以下0为不选,1为选 \(f_{i,0/1}\)为\(i\)子树的最小值,\(g_{i,0/1}\)为除i子树外的最小值 \(fh_{i,j,0/1,0/1}\)为确定\( ...

  7. 竞赛题解 - NOIP2018 保卫王国

    \(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...

  8. [NOIP2018]保卫王国(树形dp+倍增)

    我的倍增解法吊打动态 \(dp\) 全局平衡二叉树没学过 先讲 \(NOIP\) 范围内的倍增解法. 我们先考虑只有一个点取/不取怎么做. \(f[x][0/1]\) 表示取/不取 \(x\) 后,\ ...

  9. 【noip2018】【luogu5024】保卫王国

    题目描述 Z 国有nn座城市,n - 1n−1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要满足如下几个条 ...

随机推荐

  1. Windows10常用快捷键

    1. 打开注册表 ctrl+R   --->   regedit   2.打开资源管理器 win + E    3.切换到桌面 win + D   再按一次可以进行还原   4.锁屏 win+ ...

  2. vue-router的简单实现原理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. CentOS7 下面安装jdk1.8

    1. 卸载已有的jdk rpm -qa |grep jdk |xargs rpm -e --nodeps 2. 使用xftp上传 jdk 的文件我这里上传的是 jdk-8u121-linux-x64. ...

  4. CIFS 与 SMB 有什么区别?

    CIFS 与 SMB 有什么区别? https://www.getnas.com/2018/11/30/cifs-vs-smb/ 网络协议 一知半解 学习一下挺好的.. 记得 win2019 已经废弃 ...

  5. [转帖]Vim 编辑器底端 [noeol], [dos] 的含义

    Vim 编辑器底端 [noeol], [dos] 的含义 2012年11月28日 23:13:04 strongwangjiawei 阅读数:15484 https://blog.csdn.net/s ...

  6. [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告

    Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...

  7. Oracle列转行函数LISTAGG()

    --Oracle列转行函数LISTAGG() with tb_temp as( select 'China' 国家,'Wuhan' 城市 from dual union all select 'Chi ...

  8. js尾递归函数

    普通递归: function fac(n) { if (n === 1) return 1; return n * fac(n - 1); } fac(5) // 120 这是个阶乘.但是占用内存,因 ...

  9. 隐藏Nginx或Apache以及PHP的版本号的方法

    当黑客入侵一台服务器时,首先会”踩点”, 这里的”踩点”,指的是了解服务器中运行的一些服务的详细情况,比如说:版本号,当黑客知道相应服务的版本号后,就可以寻找该服务相应版本的一些漏洞来入侵,攻击,所以 ...

  10. ssm框架整合配置,用maven配置依赖jar包

    1.创建maven project 首先在pom.xml中指定工程所依赖的jar包 <project xmlns="http://maven.apache.org/POM/4.0.0& ...