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的更多相关文章

  1. luogu5024 [NOIp2018]保卫王国 (动态dp)

    可以直接套动态dp,但因为它询问之间相互独立,所以可以直接倍增记x转移到fa[x]的矩阵 #include<bits/stdc++.h> #define CLR(a,x) memset(a ...

  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保卫王国

    题目大意:给一颗有点权的树,每次规定两个点选还是不选,求这棵树的最小权点覆盖. 题解 ZZ码农题. 要用动态dp做,这题就是板子,然鹅并不会,留坑代填. 因为没有修改,所以可以静态倍增. 我们先做一遍 ...

随机推荐

  1. php ip伪装访问

    打算做个采集,无记录下来备用 php的curl搞定ip伪装来采集内容.以前写过一段代码采集一个数据来处理.由于数据量过大,同一ip采集.经常被限制,或者列为黑名单.   写了段代码伪装ip,原理是,客 ...

  2. MyBatis 3在XML文件中处理大于号小于号(<>)的方法(转)

    说明:以下方式支持XML和注解的方式. 一. 用了转义字符把>和<替换掉. AND start_date <= CURRENT_DATE AND end_date >= CUR ...

  3. Spring MVC-表单(Form)标签-文件上传(File Upload)示例(转载实践)

    以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_upload.htm 说明:示例基于Spring MVC 4.1.6. 以下示例显 ...

  4. N天学习一个linux命令之du

    用途 统计文件或者目录占用硬盘空间大小 用法 du [OPTION] [FILE]du [OPTION] --files0-from=F 常用参数 -a, --all统计所有文件,不仅仅是目录 -b, ...

  5. OpenCV+iOS开发使用文档

      一.      前言     OpenCV是开源的跨平台的计算机视觉库,实现了图像处理.计算机视觉和机器学习的很多通用算法. 对于移动设备没有快速输入的键盘,大的屏幕,其优势在于图像和声音,因此要 ...

  6. luogu3469 [POI2008]BLO_Blockade

    题目大意 给一个无向连通图,求对于每一个点,去掉该点后图中连通结点有序对的减少量. 思路 当时想这道题时,我想到:枚举每一个点,在删去它后连通的几个部分中Dfs得到各个部分的点的个数从而得到解,但是我 ...

  7. luogu2770 航空路线问题 网络流

    题目大意: 给定一张航空图,图中顶点代表城市,边代表 2 城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线.(1)从最西端城市出发,单向从西向东途经若干城市到达最东端城市,然 ...

  8. Power Network(最大流(EK算法))

    http://poj.org/problem?id=1459 题意:有一个电路网络,每个节点可以产生.传递.消耗若干电量,有点线连接结点,每个电线有最大传输量,求这个网络的最大消费量. 思路:从源点到 ...

  9. Python 40 数据库-外键约束 、多对一与多对多的处理

    mysql提供了 foreign key,专门用于为表和表之间 建立物理关联 思考 表里存储的是一条条的记录,两个表之间能产生的关系有哪些? 现有 A B两张表 1.多对一         2.一对一 ...

  10. 猜拳游戏项目(涉及知识点Scanner、Random、For、数组、Break、Continue等)

    package day03.d3.xunhuankongzhi; import java.util.Scanner; public class CaiQuan { public static void ...