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 要在城市中驻扎军队.驻扎军队需要满足如下几个条 ...
随机推荐
- 让Apache和Nginx支持php-fpm模块
Apache 对于Apache,首先是apache的安装,可以参考下面这篇博客:编译安装Apache 编辑apache配置文件,取消下面这两行的注释(删除前面的#): #LoadModule prox ...
- Git-用 cherry-pick 挑好看的小樱桃
版权声明:本文为博主原创文章,转载请在文章明显位置标明文章原属哦. https://blog.csdn.net/qq_32452623/article/details/79449534 ti ...
- CLOUD添加自定义基础数据
1.打开bos平台,文件-新建-复制-基础资料 2.新建目标对象 3.发布 4.开始新增对象 5.明细维护,完成 6.添加成功
- Hbase存储流程
- CentOS7下Nginx搭建反向代理,并使用redis保存session
1.启动两个tomcat,端口分别为8080,8081 2.配置nginx,vim /usr/local/nginx/conf/nginx.conf 添加如下配置: 3.启动nginx或热加载 启动: ...
- 在编写wpf界面时候中出现如下错误: 类型引用不明确。至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualStateManager”的类型。请考虑调整程序集 XmlnsDefinition 特性。
wpf中类型引用不明确.至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualState 你是不是用了WPFToolKit?如果是的,那原因 ...
- JS 原型和闭包
原文:深入理解javascript原型和闭包(完结) JavaScript 中的难点和重要点,排除知识体系之外的 bug.本篇是学习笔记,记录个人理解. 一.一切皆对象:一切(引用类型)都是对象,对象 ...
- SQL Server 一张图让你秒懂联合表查询
- gym-101350M
题意:给你一堆货币汇率,再给你一堆货币,算下值多少钱: 思路:直接map搞定: #include<iostream> #include<algorithm> #include& ...
- kubernetes Helm-chart web UI添加
charts web ui 添加chart仓库 helm repo add cherryleo https://fileserver-1253732882.cos.ap-chongqing.myqcl ...