DDP模板题

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define ft first
#define sd second
#define pb(a) push_back(a)
#define mp(a,b) std::make_pair(a,b)
#define ITR(a,b) for(auto a:b)
#define REP(a,b,c) for(register int a=(b),a##end=(c);a<=a##end;++a)
#define DEP(a,b,c) for(register int a=(b),a##end=(c);a>=a##end;--a)
const int MAXN=100000+10;
const ll inf=1e18,vinf=1e12;
int n,m,e,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],size[MAXN],hson[MAXN],st[MAXN],ed[MAXN],top[MAXN],fa[MAXN],w[MAXN],cnt;
ll f[MAXN][2],all;
char type[5];
template<typename T> inline bool chkmin(T &x,T y){return y<x?(x=y,true):false;}
template<typename T> inline bool chkmax(T &x,T y){return y>x?(x=y,true):false;}
struct Matrix{
ll a[2][2];
Matrix(){
REP(i,0,1)REP(j,0,1)a[i][j]=-inf;
};
inline Matrix operator * (const Matrix &A) const {
Matrix B;
REP(i,0,1)REP(k,0,1)REP(j,0,1)chkmax(B.a[i][j],a[i][k]+A.a[k][j]);
return B;
};
};
Matrix val[MAXN];
#define Mid ((l+r)>>1)
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,l,Mid
#define rson rs,Mid+1,r
struct Segment_Tree{
Matrix sum[MAXN<<2];
inline void PushUp(int rt)
{
sum[rt]=sum[ls]*sum[rs];
}
inline void Build(int rt,int l,int r)
{
if(l==r)sum[rt]=val[l];
else Build(lson),Build(rson),PushUp(rt);
}
inline void Update(int rt,int l,int r,int ps,Matrix k)
{
if(l==r)sum[rt]=k;
else
{
if(ps<=Mid)Update(lson,ps,k);
else Update(rson,ps,k);
PushUp(rt);
}
}
inline Matrix Query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return sum[rt];
else
{
if(R<=Mid)return Query(lson,L,R);
else if(L>Mid)return Query(rson,L,R);
else return Query(lson,L,R)*Query(rson,L,R);
}
}
};
Segment_Tree T;
#undef Mid
#undef ls
#undef rs
#undef lson
#undef rson
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs1(int x,int p)
{
int res=0;
size[x]=1;fa[x]=p;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==p)continue;
else
{
dfs1(to[i],x);
size[x]+=size[to[i]];
if(chkmax(res,size[to[i]]))hson[x]=to[i];
}
}
inline void dfs2(int x,int tp)
{
top[x]=tp;st[x]=++cnt;
val[cnt].a[0][0]=val[cnt].a[0][1]=f[x][0];
val[cnt].a[1][0]=f[x][1];
if(hson[x])
{
val[cnt].a[0][0]-=max(f[hson[x]][0],f[hson[x]][1]);
val[cnt].a[0][1]=val[cnt].a[0][0];
val[cnt].a[1][0]-=f[hson[x]][0];
dfs2(hson[x],tp);ed[x]=ed[hson[x]];
}
else ed[x]=cnt;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==fa[x]||to[i]==hson[x])continue;
else dfs2(to[i],to[i]);
}
inline void dfs(int x)
{
f[x][1]=w[x];
for(register int i=beg[x];i;i=nex[i])
if(to[i]==fa[x])continue;
else
{
dfs(to[i]);
f[x][1]+=f[to[i]][0];
f[x][0]+=max(f[to[i]][0],f[to[i]][1]);
}
}
inline void init()
{
dfs1(1,0);dfs(1);dfs2(1,1);
T.Build(1,1,n);
}
inline void solve(int u,ll v)
{
Matrix A,B,C;
B=T.Query(1,1,n,st[u],st[u]);
A=T.Query(1,1,n,st[top[u]],ed[u]);
B.a[1][0]+=v;
T.Update(1,1,n,st[u],B);
while(u)
{
B=T.Query(1,1,n,st[top[u]],ed[u]);
u=fa[top[u]];
if(!u)break;
C=T.Query(1,1,n,st[u],st[u]);
C.a[0][0]+=max(B.a[0][0],B.a[1][0])-max(A.a[0][0],A.a[1][0]);
C.a[0][1]=C.a[0][0];
C.a[1][0]+=B.a[0][0]-A.a[0][0];
A=T.Query(1,1,n,st[top[u]],ed[u]);
T.Update(1,1,n,st[u],C);
}
}
inline ll value(int ot1,int ot2)
{
Matrix A=T.Query(1,1,n,st[1],ed[1]);
return max(A.a[0][0],A.a[1][0])+(ot1?0:-vinf)+(ot2?0:-vinf);
}
int main()
{
freopen("defense.in","r",stdin);
freopen("defense.out","w",stdout);
read(n);read(m);scanf("%s",type);
REP(i,1,n)read(w[i]),all+=w[i];
REP(i,1,n-1)
{
int u,v;read(u);read(v);
insert(u,v);insert(v,u);
}
init();
while(m--)
{
int a,x,b,y;read(a);read(x);read(b);read(y);
if((fa[a]==b||fa[b]==a)&&!x&&!y)
{
puts("-1");
continue;
}
solve(a,x?-vinf:vinf);
solve(b,y?-vinf:vinf);
printf("%lld\n",all-value(x,y));
solve(a,x?vinf:-vinf);
solve(b,y?vinf:-vinf);
}
return 0;
}

【比赛】NOIP2018 保卫王国的更多相关文章

  1. 竞赛题解 - NOIP2018 保卫王国

    \(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...

  2. [NOIP2018]保卫王国 题解

    NOIP2018提高组D2T3 ddp虽然好想,但是码量有点大(其实是我不会),因此本文用倍增优化树形DP来解决本题. 题意分析 给一棵树染色,每个节点染色需要一定的花费,要求相邻两个节点至少要有一个 ...

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

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

  4. NOIP2018保卫王国

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

  5. 2019.02.16 bzoj5466: [Noip2018]保卫王国(链分治+ddp)

    传送门 题意简述: mmm次询问,每次规定两个点必须选或者不选,求树上的带权最小覆盖. 思路: 考虑链分治+ddpddpddp 仍然是熟悉的套路,先考虑没有修改的状态和转移: 令fi,0/1f_{i, ...

  6. [NOIP2018]保卫王国

    嘟嘟嘟 由于一些知道的人所知道的,不知道的人所不知道的原因,我来发NOIP2018day2T3的题解了. (好像我只是个搬运工--) 这题真可以叫做NOIplus了,跟其他几道比较水的题果然不一样,无 ...

  7. [NOIP2018]保卫王国(树形dp+倍增)

    我的倍增解法吊打动态 \(dp\) 全局平衡二叉树没学过 先讲 \(NOIP\) 范围内的倍增解法. 我们先考虑只有一个点取/不取怎么做. \(f[x][0/1]\) 表示取/不取 \(x\) 后,\ ...

  8. 「NOIP2018 保卫王国」

    题目 强制选点我们可以把那个点权搞成\(-inf\),强制不选我们搞成\(inf\),之后就真的成为动态\(dp\)的板子题了 由于不想像板子那样再写一个最大独立集的方程,之后利用最小点覆盖=总点权- ...

  9. BZOJ5466 NOIP2018保卫王国(倍增+树形dp)

    暴力dp非常显然,设f[i][0/1]表示i号点不选/选时i子树内的答案,则f[i][0]=Σf[son][1],f[i][1]=a[i]+Σmin(f[son][0],f[son][1]). 注意到 ...

随机推荐

  1. MySQL使用select查询时,在查询结果中增加一个字段并指定固定值

    假设需求是这样的: mysql> desc user; +-------+----------+------+-----+---------+----------------+ | Field ...

  2. pinpoint vs druid

    主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid) - ppjj - 博客园 https://www.cnblogs.com/nizuimeiabc1/ ...

  3. React Native之微信分享(iOS Android)

    React Native之微信分享(iOS Android) 在使用React Native开发项目的时候,基本都会使用到微信好友或者微信朋友圈分享功能吧,那么今天我就带大家实现以下RN微信好友以及朋 ...

  4. C# Note4:XML序列化和反序列化(含加密解密等)

    前言 在项目中,我们经常用到各种配置文件,比如xml文件.binary文件等等,这里主要根据实践经验介绍下xml文件的序列化和反序列化(毕竟最常用). 实践背景:我要做一个用户管理功能,用户账号信息存 ...

  5. rpm和yum

    RMP(红帽软件包管理器) RPM有点像Windows系统中的控制面板,会建立统一的数据库文件,详细记录软件信息并能够自动分析依赖关系. YUM(软件仓库)

  6. Golang的md5 hash计算

    Golang计算md5值的方法都是接收byte型slice([]byte).而且使用习惯上也觉得略奇怪. 看了好几个例子才看懂. 感觉Golang标准库在设计这些模块的时候,都会考虑使用带New关键字 ...

  7. Linux基础学习(12)--Linux服务管理

    第十二章——Linux服务管理 一.服务简介与分类 1.服务的分类: 注:独立的服务放在内存中(好处:响应的速率快,坏处:独立的服务越多,耗费的内存资源越多):xinetd服务本身是独立的,在内存中, ...

  8. How to proof RSA

    欧拉函数 :欧拉函数是数论中很重要的一个函数,欧拉函数是指:对于一个正整数 n ,小于 n 且和 n 互质的正整数(包括 1)的个数,记作 φ(n) . 完全余数集合:定义小于 n 且和 n 互质的数 ...

  9. 学习 Spring (十五) Advisor

    Spring入门篇 学习笔记 advisor 就像一个小的自包含的方面,只有一个 advice 切面自身通过一个 bean 表示,并且必须实现某个 advice 接口,同时 advisor 也可以很好 ...

  10. asp.net core mvc ajaxform submit files

    <form id="form1" method="post" enctype="multipart/form-data" asp-co ...