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. java.lang.ClassFormatError: Unknown constant tag 0 in class file

    在通过文件上传之后,运行java程序,突然发现这么一个错误:java.lang.ClassFormatError: Unknown constant tag 0 in class file,通过网上查 ...

  2. sum求和类题目

    今天看到这道题目:http://www.cnblogs.com/charlesblc/p/5930311.html 题目地址:https://leetcode.com/problems/split-a ...

  3. D. Multiplication Table 二分查找

    刚做这道题根本没想到二分,最关键是没想出来怎样统计在这个矩阵中比一个数小的有几个怎么算.造成自己想了好久最后看了别人的提示才做出来.哎.好久不做题太弱了 #include<iostream> ...

  4. Eclipse集成Resinserver

        因为Resin在Eclipse下的表现丝毫不亚于Tomcat,小编决定带领众小弟一起学习使用Resin.虽然小编身边也没有什么大牛在使用Resin,但看到Resin的广告已经吹到天边了.所以还 ...

  5. Oracle 静态监听注冊具体解释

    Oracle 静态监听注冊具体解释 网上有非常多关于oracle 监听静态注冊的文章.但大多都是简单说说,并没有具体的样例.这里,将结合linux as4 下的oracle 10gR2.0.1 举一个 ...

  6. RedisUtil: Jedis连接自动释放

    package cloud.app.prod.home.utils; import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedi ...

  7. python pickle to json

    ref: https://gist.github.com/Samurais/567ebca0f59c612eb977065008aad867 ''' Convert a pkl file into j ...

  8. mac os lscpu 【转】

    CPU Information on Linux and OS X This is small blog post detailing how to obtain information on you ...

  9. bzoj 4709 [ Jsoi2011 ] 柠檬 —— 斜率优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 课上讲的题,还是参考了博客...:https://www.cnblogs.com/GX ...

  10. bzoj4004 [JLOI2015]装备购买——线性基+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 今天讲课讲到的题,据说满足拟阵的性质,所以贪心是正确的: 总之就贪心,按价格从小到大排 ...