luogu5024 [NOIp2018]保卫王国 (动态dp)
可以直接套动态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)的更多相关文章
- BZOJ 5466: [Noip2018]保卫王国 动态DP
Code: // luogu-judger-enable-o2 #include<bits/stdc++.h> #define ll long long #define lson (now ...
- JZOJ5966. [NOIP2018TGD2T3] 保卫王国 (动态DP做法)
题目大意 这还不是人尽皆知? 有一棵树, 每个节点放军队的代价是\(a_i\), 一条边连接的两个点至少有一个要放军队, 还有\(q\)次询问, 每次规定其中的两个一定需要/不可放置军队, 问这样修改 ...
- 【NOIP2018】保卫王国 动态dp
此题场上打了一个正确的$44pts$,接着看错题疯狂$rush$“正确”的$44pts$,后来没$rush$完没将之前的代码$copy$回去,直接变零分了..... 这一题我们显然有一种$O(nm)$ ...
- luoguP5024 保卫王国 动态dp
题目大意: emmmmm 题解: QAQ #include <cstdio> #include <cstring> #include <iostream> usin ...
- LuoguP5024 保卫王国(动态DP,LCT)
最小权覆盖集 = 全集 - 最大权独立集 强制取点.不取点可以使用把权值改成正无穷或负无穷实现 接下来就是经典的"动态最大权独立集"了 O(nlogn). 这不是我说的,是immo ...
- P5024 保卫王国(动态dp/整体dp/倍增dp)
做法(倍增) 最好写的一种 以下0为不选,1为选 \(f_{i,0/1}\)为\(i\)子树的最小值,\(g_{i,0/1}\)为除i子树外的最小值 \(fh_{i,j,0/1,0/1}\)为确定\( ...
- 竞赛题解 - NOIP2018 保卫王国
\(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...
- [NOIP2018]保卫王国(树形dp+倍增)
我的倍增解法吊打动态 \(dp\) 全局平衡二叉树没学过 先讲 \(NOIP\) 范围内的倍增解法. 我们先考虑只有一个点取/不取怎么做. \(f[x][0/1]\) 表示取/不取 \(x\) 后,\ ...
- 【noip2018】【luogu5024】保卫王国
题目描述 Z 国有nn座城市,n - 1n−1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需要满足如下几个条 ...
随机推荐
- WebSocket实现一个聊天室
聊天室页面-->index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8&q ...
- 简述HTTP协议
引言 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议.HTTP 是基于 TCP/IP 协议通信协议 ...
- 完美解决safari、微信浏览器下拉回弹效果
CSS代码: .box{ overflow: auto; -webkit-overflow-scrolling: touch; } HTML代码: <body class="box&q ...
- socket通信原理三次握手和四次握手详解
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP?2. Sock ...
- redhat7通过yum安装nginx最新版
1.准备yum源 vi /etc/yum.repo.d/nginx.repo [nginx]name=nginx repobaseurl=http://nginx.org/packages/mainl ...
- 和docket的第一次亲密接触
很久很久以前,第一次听说docker时,感觉很高大上,同时自我感觉会很难.所以一直没有详细了解.前一段时间偶尔看到关于docker的详细介绍,于是乎来了兴趣.自已折腾了一下,发现不是想象中的那么难. ...
- MyBatis SpringBoot 杂记
最近接了个xxx代码. 不能说人家不好, 因为必进年月久了.能用这么长时间, 不就说明还不错么?! 我们现在每天写的, 能超出人家的么~~~ 呵呵 Java项目中, 把动态数据源切换的框架整合进来. ...
- linux 依赖解决办法
在安装软件过程中如果出现依赖不满足,有两种情况: 1:你系统里面没有安装依赖软件,[但是你的软件源里面有这个软件,你只是没有安装], 这种情况很简单,通过 sudo apt-get install - ...
- 1.ansible基本参数介绍
想使用ansible 先--help学习下基本的options吧小兄弟1: -m 指定模块名称只有一个模块command 可以省略:-M 指出模块路径来加载2: -a 指定模块参数就是模块的内容你知道 ...
- FMC
FMC (FPGA Mezzanine Card) 编辑 FMC:英文全称,FPGA Mezzanine Card.是一个应用范围.适应环境范围和市场领域范围都很广的通用模块.FMC连接器(FMC C ...