BZOJ 5466: [Noip2018]保卫王国 动态DP
Code:
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define ll long long
#define lson (now<<1)
#define rson ((now<<1)|1)
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 300000
const long long inf = 100000000000000;
using namespace std;
char uuu[9];
ll V[maxn];
int fa[maxn],hd[maxn],to[maxn],nex[maxn],siz[maxn],hson[maxn];
int F[maxn][2];
int top[maxn],bot[maxn],dfn[maxn],ln[maxn];
int edges,tim,n,Q;
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
struct Matrix
{
ll a[2][2];
ll*operator[](int x){return a[x]; }
}t[maxn<<1],tmp[maxn];
Matrix operator*(Matrix a,Matrix b)
{
Matrix c;
c[0][0]=min(a[0][0]+b[0][0],a[0][1]+b[1][0]);
c[0][1]=min(a[0][0]+b[0][1],a[0][1]+b[1][1]);
c[1][0]=min(a[1][0]+b[0][0],a[1][1]+b[1][0]);
c[1][1]=min(a[1][0]+b[0][1],a[1][1]+b[1][1]);
return c;
}
void dfs1(int u,int ff)
{
fa[u]=ff,siz[u]=1;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[hson[u]]) hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp,ln[++tim]=u,dfn[u]=tim;
if(hson[u])
dfs2(hson[u],tp),bot[u]=bot[hson[u]];
else
bot[u]=u;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==fa[u]||v==hson[u]) continue;
dfs2(v,v);
}
}
void dfs(int u)
{
F[u][0]=0,F[u][1]=V[u];
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==fa[u]) continue;
dfs(v);
F[u][0]+=F[v][1];
F[u][1]+=min(F[v][0],F[v][1]);
}
}
void build(int l,int r,int now)
{
if(l>r) return;
if(l==r)
{
int u=ln[l];
ll f0=0,f1=V[u];
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==fa[u]||v==hson[u]) continue;
f0+=F[v][1];
f1+=min(F[v][0],F[v][1]);
}
t[now]=tmp[l]=(Matrix){inf, f0,f1,f1};
return;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
t[now]=t[lson]*t[rson];
}
void modify(int l,int r,int now,int p)
{
if(l==r)
{
t[now]=tmp[l];
return;
}
int mid=(l+r)>>1;
if(p<=mid)
modify(l,mid,lson,p);
else
modify(mid+1,r,rson,p);
t[now]=t[lson]*t[rson];
}
Matrix query(int l,int r,int now,int L,int R)
{
if(l==L&&r==R) return t[now];
int mid=(l+r)>>1;
if(R<=mid) return query(l,mid,lson,L,R);
if(L>mid) return query(mid+1,r,rson,L,R);
return query(l,mid,lson,L,mid)*query(mid+1,r,rson,mid+1,R);
}
void Update(int u,ll w)
{
tmp[dfn[u]][1][0]=tmp[dfn[u]][1][1]+=w-V[u], V[u]=w;
while(u)
{
Matrix a=query(1,n,1,dfn[top[u]],dfn[bot[u]]);
modify(1,n,1,dfn[u]);
Matrix b=query(1,n,1,dfn[top[u]],dfn[bot[u]]);
u=fa[top[u]];
if(!u) return;
int x=dfn[u];
ll f0=a[0][1],f1=a[1][1],g0=b[0][1],g1=b[1][1];
tmp[x][1][0]=tmp[x][1][1]=tmp[x][1][0]+min(g1,g0)-min(f1,f0);
tmp[x][0][1]=tmp[x][0][1]+g1-f1;
}
}
void solve(int a,int x,int b,int y)
{
if(!x&&!y&&(fa[a]==b||fa[b]==a)) { printf("-1\n"); return ;}
ll o=V[a],oo=V[b];
Update(a,x?o-inf:o+inf), Update(b,y?oo-inf:oo+inf);
Matrix ans=query(1,n,1,dfn[top[1]],dfn[bot[1]]);
ll h=min(ans[0][1],ans[1][1]);
if(x) h+=inf;
if(y) h+=inf;
printf("%lld\n",h);
Update(a,o), Update(b,oo);
}
int main()
{
// setIO("input");
scanf("%d%d%s",&n,&Q,uuu);
for(int i=1;i<=n;++i) scanf("%lld",&V[i]);
for(int i=1,u,v;i<n;++i) scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs1(1,0),dfs2(1,1),dfs(1),build(1,n,1);
while(Q--)
{
int a,x,b,y;
scanf("%d%d%d%d",&a,&x,&b,&y);
solve(a,x,b,y);
}
return 0;
}
BZOJ 5466: [Noip2018]保卫王国 动态DP的更多相关文章
- luogu5024 [NOIp2018]保卫王国 (动态dp)
可以直接套动态dp,但因为它询问之间相互独立,所以可以直接倍增记x转移到fa[x]的矩阵 #include<bits/stdc++.h> #define CLR(a,x) memset(a ...
- 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保卫王国
题目大意:给一颗有点权的树,每次规定两个点选还是不选,求这棵树的最小权点覆盖. 题解 ZZ码农题. 要用动态dp做,这题就是板子,然鹅并不会,留坑代填. 因为没有修改,所以可以静态倍增. 我们先做一遍 ...
随机推荐
- Python3-paramiko-SFTP上传文件夹到多台远程服务器
# coding: utf-8 import paramiko import re import os from time import sleep # 定义一个类,表示一台远端linux主机 # 参 ...
- DTrace Probes In MySQL 自定义探针
Inserting user-defined DTrace probes into MySQL source code is very useful to help user identify the ...
- 个人常常使用的一些Eclipse技巧
引言 为了加快开发效率,方便地浏览源代码,重构以及重写一些方法等,Eclipse给我们提供了非常多方便的快捷键以及小技巧.以下是我总结一下经常使用的快捷键和技巧. 快捷键 清理控制台(console) ...
- HPU 1002 A + B Problem II【大数】
A + B Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Ubuntu14.04下Android系统与应用开发软件完整apt-get 源。
# deb cdrom:[Ubuntu 14.04.1 LTS _Trusty Tahr_ - Release amd64 (20140722.2)]/ trusty main restricted# ...
- mongo集群的监控(一)
由于工作中总是遇到一些私有化部署和不同环境的mongo server异常,为了统一方便的监控其运行情况,我筛选了多个工具,最终选择了motop. motop是一款用python编写的实时监控工具,可以 ...
- javaweb项目中获取项目名称
request.getServletContext().getContextPath() 增加项目名称是test.那么上面的结果就是/test
- THRDTERM-----干净地结束一个线程
THRDTERM产生两个线程.周期性地检查一个event对象.以决定要不要结束自己. #define WIN32_LEAN_AND_MEAN #include<stdio.h> #incl ...
- rk3288对于parameter参数文件的解析处理【转】
本文转载自:http://blog.csdn.net/groundhappy/article/details/56479694 rk3288有一个parameter文件. 类似于 FIRMWARE_V ...
- 【POJ 1456】 Supermarket
[题目链接] http://poj.org/problem?id=1456 [算法] 贪心 + 堆 [代码] #include <algorithm> #include <bitse ...