传送门

我现在还是不明白为什么NOIPd2t3会是一道动态dp……

首先关于动态dp可以看这里

然后这里就是把把矩阵给改一改,改成这个形式\[\left[dp_{i-1,0},dp_{i-1,1}\right]\times \left[\begin{matrix}\infty&ldp_{i,1}\\ldp_{i,0}&ldp_{i,1}\end{matrix}\right]\]

然后就是改成\(longlong\),以及改一改取最小。关于强制取或不取,只要让值加上一个极大值或减去极大值就可以了

于是这么想着并交上去的我就调了一天

这里最主要的问题是,因为矩乘之后,第二行的两个数才是\(dp_{i,0}\)和\(dp_{i,1}\),然后没发现这点,于是就没有于是了……

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define mx 1e10
#define inf 1e12
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f;
}
inline void getstr(){char ch;while((ch=getc())<'A'||ch>'Z');while((ch=getc())>='A'&&ch<='Z');}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R ll x){if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5;
inline ll min(R ll x,R ll y){return x<y?x:y;}
inline ll max(R ll x,R ll y){return x>y?x:y;}
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int sz[N],lsz[N],val[N],son[N],fat[N],n,m;
void dfs(int u,int fa){sz[u]=1;go(u)if(v!=fa){fat[v]=u,dfs(v,u),sz[u]+=sz[v];if(sz[v]>sz[son[u]])son[u]=v;}lsz[u]=sz[u]-sz[son[u]];
}
struct Matrix{ll a[2][2];Matrix(){a[0][0]=a[0][1]=a[1][0]=a[1][1]=inf;}Matrix(R int x){a[0][0]=a[1][1]=0,a[0][1]=a[1][0]=inf;}inline ll mn(){return min(min(a[0][0],a[0][1]),min(a[1][0],a[1][1]));}inline ll* operator [](const int &x){return a[x];}Matrix operator *(Matrix b){Matrix res;res[0][0]=min(a[0][0]+b[0][0],a[0][1]+b[1][0]);res[0][1]=min(a[0][0]+b[0][1],a[0][1]+b[1][1]);res[1][0]=min(a[1][0]+b[0][0],a[1][1]+b[1][0]);res[1][1]=min(a[1][0]+b[0][1],a[1][1]+b[1][1]);return res;}
}mul[N],w[N];int ch[N][2],fa[N],st[N],top,rt;bool vis[N];
inline void upd(R int u){mul[u]=mul[ch[u][0]]*w[u]*mul[ch[u][1]];}
inline void pd(R int u,R int v){w[u][0][1]+=mul[v].mn(),w[u][1][1]=w[u][0][1],w[u][1][0]+=mul[v][1][1],fa[v]=u;
}
inline bool is(R int u){return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;}
inline void init(){fp(i,1,n)w[i][0][1]=w[i][1][1]=val[i],w[i][1][0]=0,mul[i]=w[i];}
int sbuild(int l,int r){if(l>r)return 0;int tot=0;fp(i,l,r)tot+=lsz[st[i]];for(int i=l,now=lsz[st[i]];i<=r;++i,now+=lsz[st[i]])if(now*2>=tot){ch[st[i]][0]=sbuild(i+1,r),ch[st[i]][1]=sbuild(l,i-1);fa[ch[st[i]][0]]=fa[ch[st[i]][1]]=st[i],upd(st[i]);return st[i];}
}
int build(int u){for(int p=u;p;p=son[p])vis[p]=1;for(int p=u;p;p=son[p])go(p)if(!vis[v])pd(p,build(v));top=0;for(int p=u;p;p=son[p])st[++top]=p;return sbuild(1,top);
}
void update(int u,int vva){w[u][0][1]+=vva?-mx:mx,w[u][1][1]=w[u][0][1];for(R int p=u;p;p=fa[p])if(is(p)&&fa[p]){w[fa[p]][0][1]-=mul[p].mn(),w[fa[p]][1][1]=w[fa[p]][0][1];w[fa[p]][1][0]-=mul[p][1][1],upd(p);w[fa[p]][0][1]+=mul[p].mn(),w[fa[p]][1][1]=w[fa[p]][0][1];w[fa[p]][1][0]+=mul[p][1][1];}else upd(p);
}
int f[N][2];
void dp(int u,int fa){f[u][0]=0,f[u][1]=val[u];go(u)if(v!=fa){dp(v,u),f[u][0]+=f[v][1],f[u][1]+=min(f[v][0],f[v][1]);}
}
int main(){
//  freopen("testdata.in","r",stdin);w[0]=mul[0]=Matrix(1),n=read(),m=read(),getstr();fp(i,1,n)val[i]=read();for(R int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);dfs(1,0),init(),rt=build(1);while(m--){int u=read(),x=read(),v=read(),y=read();if((u==fat[v]||v==fat[u])&&!x&&!y)print(-1);else{update(u,x),update(v,y);print(mul[rt].mn()+(x+y)*mx);update(u,x^1),update(v,y^1);}}return Ot(),0;
}

转载于:https://www.cnblogs.com/bztMinamoto/p/10192659.html

P5024 保卫王国相关推荐

  1. 线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国

    动态DP--广义矩阵加速 SP1716 GSS3 - Can you answer these queries III description solution code [NOIP2018 提高组] ...

  2. Uoj 441 保卫王国

    Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题. 设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]=\sum ...

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

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

  4. 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]). 注意到 ...

  5. 2018 NOIP 提高组 复赛 day2

    文章目录 T1 旅行 T1 分析 T2 填数游戏 T2 分析 T3 保卫王国 T3 分析 不得不说-noip的趋势越来越像是day1基础+思路稳定分数,基本确定你能在哪个获奖区,day2难度提高,给满 ...

  6. 2020.7月做题记录

    转眼就到了2020的下半年了-前方仍是一片茫然. 长期计划 prufer 序列 2020.07.02-2020.07.04 Problem Finished P2624 [HNOI2008]明明的烦恼 ...

  7. NOIP2018提高组比赛总结

    NOIP2018提高组比赛总结 前言 新赛季,依旧有很多失误. 在些许的遗憾和无奈中,NOIP2018,撒花结束 纵观今年的整一场NOIP,有许多值得总结的地方 正文 NOIP2018初赛 第二次参加 ...

  8. noip2018——题解总结

    近期正在疯狂复习某些东西,这篇博客尽量年底更完--(Day2T2除外) 好了,所有的希望都破灭了,原来这就是出题人的素质.--一个被欺骗的可怜 $OIer$ 人生中倒数第三次 $noip$ (Mayb ...

  9. [总结] 动态DP学习笔记

    学习了一下动态DP 问题的来源: 给定一棵 \(n\) 个节点的树,点有点权,有 \(m\) 次修改单点点权的操作,回答每次操作之后的最大带权独立集大小. 首先一个显然的 \(O(nm)\) 的做法就 ...

最新文章

  1. 工程师文化:BAT 为什么不喊老板
  2. 未来CRM的趋势和预测
  3. (Java常用类)Object类
  4. 小程序 数据库 时间_使用云开发数据库构建更生动的小程序
  5. JavaScript学习总结(三)——逻辑And运算符详解
  6. 基于php5.6 php.ini详解
  7. [转载] Linux里面的文件目录类指令
  8. 哪几所大学计算机软件方面是强项,计算机软件工程专业排名靠前的大学是那几所...
  9. 作为技术工程师,到底需要怎样的专业能力
  10. 代码是写给人看的还是写给机器看的?
  11. 各行各业有对象系列之三:对象存储与银行
  12. iMX8MM linux5.15.32移植
  13. java开发需要英语吗_学习Java开发英语不好的可以学吗?
  14. 广义瑞利商_LDA里的瑞利商和广义瑞利商
  15. 在终端输入“python”或者”pip“时出现python’不是内部或外部命令,也不是可运行的程序 或批处理文件
  16. 华为应用市场2021年度安全隐私报告发布:护航应用安全是场“持久战”
  17. jenkins发送allure测试报告
  18. SpringBoot整合druid数据源,quartz定式框架
  19. CISP查询具体步骤
  20. Linux基础、Shell基础语法等

热门文章

  1. 《MySQL——如何解决一主多从的读写分离的过期读问题》
  2. vector向量容器
  3. ffplay分析 (暂停 / 播放处理)
  4. php的变量、传值、传址、销毁变量
  5. python中注释语句和运算_python 运算及注释
  6. linux堆上的内存可执行吗,pwn的艺术浅谈(二):linux堆相关
  7. wpa_supplicant wifi密码错误检测
  8. 树莓派第一次开机自动连接WIFI(不用显示屏方法)
  9. 【Leetcode | 顺序刷题】杂项目录
  10. mysql数据库引擎怎么看,值得收藏!