LOJ3044. 「ZJOI2019」Minimax 搜索

https://loj.ac/problem/3044

分析:

  • 假设\(w(1)=W\),那么使得这个值变化只会有两三种可能,比\(W\)小的值变成\(W+1\),比\(W\)大的值变成\(W-1\),或直接修改\(W\)。
  • 先考虑第一部分,设\(f_{x}\)表示只改变权值\(<W\)的节点,\(x\)节点权值\(\le W\)的概率,这样能推出\(dp\)式子
  • \(f_x=\prod\limits_{t}f_t​\) \((dep_x\ is \ odd)​\)
  • \(f_x=1-\prod\limits_{t}(1-f_t)​\) \((dep_x\ is\ even)​\)
  • 手动展开可以发现\(f'_x=\prod\limits_{t}(1-f'_x)​\) \((f'_x=(-1)^{dep_x+1}f_x)​\)
  • 对于另一个,我们设\(g_x\)表示只改变\(>W\)的点,\(x\)节点权值\(<W\)的概率,这样使得两个转移方程相同。
  • 然后对于不同的\(K\)可以看做是对两个节点的修改,动态\(dp\)即可。

\(f_x=\prod\limits_{t\in child_x}(1-f_t)​\)

设\(g_x=\prod\limits_{t\in child_x,t\not =s}(1-f_t)\) \(s\)为\(x\)的重儿子

那么\(f_x=(1-f_s)\times g_x\)

\(=g_x-f_s\times g_x\)

\(\left[ \begin{matrix}-g_x&g_x\\0&1\end{matrix}\right]\times \left[\begin{matrix}f_s\\1\end{matrix}\right]=\left[\begin{matrix}f_x\\1\end{matrix}\right]\)

容易发现矩阵只需要存左上和右上,用两个变量维护即可。

这里可能需要除\(0​\),需要记录一下非\(0​\)部分和\(0​\)的数量。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <iostream>
using namespace std;
#define N 200050
#define mod 998244353
#define ls ch[p][0]
#define rs ch[p][1]
#define db(x) cerr<<#x<<" = "<<x<<endl
const int inv2=(mod+1)/2;
typedef long long ll;
int head[N],to[N<<1],nxt[N<<1],cnt,n,du[N],dep[N],fa[N],L,R,w[N];
int siz[N],lf[N],son[N],sz[N],top[N],val[N],S[N];
ll ans[N],mi[N];
ll qp(ll x,ll y=mod-2) {
ll re=1;for(;y;y>>=1,x=x*x%mod) if(y&1) re=re*x%mod; return re;
}
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void df1(int x,int y) {
int i;
siz[x]=lf[x];
fa[x]=y;
sz[x]=1;
dep[x]=dep[y]+1;
if(dep[x]&1) w[x]=0;
else w[x]=n;
for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
df1(to[i],x);
siz[x]+=siz[to[i]];
sz[x]+=sz[to[i]];
if(dep[x]&1) w[x]=max(w[x],w[to[i]]);
else w[x]=min(w[x],w[to[i]]);
if(sz[to[i]]>sz[son[x]]) son[x]=to[i];
}
if(lf[x]) w[x]=x;
val[x]=sz[x]-sz[son[x]];
}
struct A {
ll x; int t;
A() {x=0,t=0;}
A(ll x_,int t_) {x=x_,t=t_;}
void operator *= (const ll &u) {
if(!u) t++;
else x=x*u%mod;
}
void operator /= (const ll &u) {
if(!u) t--;
else x=x*qp(u)%mod;
}
operator ll() {return t?0:x;}
};
struct Mat {
ll l,r;
Mat() {}
Mat(ll l_,ll r_) {l=l_,r=r_;}
Mat operator * (const Mat &u) const {
return Mat(l*u.l%mod,(l*u.r+r)%mod);
}
}I;
struct Tree {
int ch[N][2],f[N];
A dp[N]; Mat F[N];
int flg,rt;
bool isrt(int x) {return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
void pushup(int p) {
F[p]=Mat(-dp[p],dp[p]);
if(ls) F[p]=F[ls]*F[p];
if(rs) F[p]=F[p]*F[rs];
}
int build(int l,int r) {
if(l>r) return 0;
int sum=0,i,p,x=0;
for(i=l;i<=r;i++) sum+=val[S[i]];
for(i=l;i<=r;i++) {
x+=val[S[i]];
if((x<<1)>=sum) break;
}
p=S[i];
ls=build(l,i-1),rs=build(i+1,r);
if(ls) f[ls]=p;
if(rs) f[rs]=p;
if(!son[p]) {
if(flg==0) dp[p].x=(p<w[1]);
else dp[p].x=1-(p>w[1]);
if(!(dep[p]&1)) dp[p].x=1-dp[p].x;
}
pushup(p);
return p;
}
int dfs(int rr) {
int t,i,x;
for(x=rr;x;x=son[x]) {
dp[x].x=1;
for(i=head[x];i;i=nxt[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) {
t=dfs(to[i]);
f[t]=x;
dp[x]*=(1-F[t].r);
}
}
int tp=0;
for(x=rr;x;x=son[x]) S[++tp]=x;
return build(1,tp);
}
void init() {
F[0]=I;
rt=dfs(1);
}
void UPD(int p,ll x) {
//puts("FUCK");
dp[p]=A(x,0);
for(;p;p=f[p]) {
if(isrt(p)) dp[f[p]]/=(1-F[p].r);
pushup(p);
if(isrt(p)) dp[f[p]]*=(1-F[p].r);
}
}
}T0,T1;
int main() {
I.l=1,I.r=0;
scanf("%d%d%d",&n,&L,&R);
int i,x,y;
for(mi[0]=i=1;i<=n;i++) mi[i]=mi[i-1]*2%mod;
for(i=1;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x),du[x]++,du[y]++;
for(i=2;i<=n;i++) if(du[i]==1) lf[i]=1;
df1(1,0);
T0.flg=0,T1.flg=1,T0.init(),T1.init();
//for(i=1;i<=n;i++) db(T0.dp[i]);
for(i=1;i<n;i++) {
//printf("%lld %lld\n",T0.F[T0.rt].r,T1.F[T1.rt].r);
x=w[1]+i-1;
if(x>w[1]&&x<=n&&lf[x]) T0.UPD(x,inv2);
x=w[1]-i+1;
if(x>0&&x<w[1]&&lf[x]) T1.UPD(x,inv2);
ll v1=1-T0.F[T0.rt].r,v2=T1.F[T1.rt].r;
ans[i]=(mi[siz[1]]-(mi[siz[1]-1])*(v1*v2%mod))%mod;
}
ans[n]=mi[siz[1]]-1;
for(i=R;i>=L;i--) {
ans[i]=(ans[i]-ans[i-1])%mod;
}
for(i=L;i<=R;i++) {
printf("%lld ",(ans[i]+mod)%mod);
}
return 0;
}

LOJ3044. 「ZJOI2019」Minimax 搜索的更多相关文章

  1. Loj #3044. 「ZJOI2019」Minimax 搜索

    Loj #3044. 「ZJOI2019」Minimax 搜索 题目描述 九条可怜是一个喜欢玩游戏的女孩子.为了增强自己的游戏水平,她想要用理论的武器武装自己.这道题和著名的 Minimax 搜索有关 ...

  2. 【LOJ】#3044. 「ZJOI2019」Minimax 搜索

    LOJ#3044. 「ZJOI2019」Minimax 搜索 一个菜鸡的50pts暴力 设\(dp[u][j]\)表示\(u\)用\(j\)次操作能使得\(u\)的大小改变的方案数 设每个点的初始答案 ...

  3. [LOJ#3044][动态DP]「ZJOI2019」Minimax 搜索

    题目传送门 容易想到一种暴力 DP:先转化成对于每个 \(k\) 求出 \(\max_{i\in S}|i-w_i|\le k\) 的方案数,最后差分 然后问题转化成每个叶子的权值有个取值区间,注意这 ...

  4. 「ZJOI2019」Minmax搜索

    传送门 Solution 叶子节点的变化区间是连续的,可得知非叶子节点的权值变化区间也是连续的 由此可知,\(W\)的变化值的可行域也是连续的,所以只需要看它能否变为\(W+1\)或\(W-1\) 对 ...

  5. 「ZJOI2019」&「十二省联考 2019」题解索引

    「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...

  6. loj#2537. 「PKUWC2018」Minimax

    题目链接 loj#2537. 「PKUWC2018」Minimax 题解 设\(f_{u,i}\)表示选取i的概率,l为u的左子节点,r为u的子节点 $f_{u,i} = f_{l,i}(p \sum ...

  7. Loj #3045. 「ZJOI2019」开关

    Loj #3045. 「ZJOI2019」开关 题目描述 九条可怜是一个贪玩的女孩子. 这天,她和她的好朋友法海哥哥去玩密室逃脱.在他们面前的是 \(n\) 个开关,开始每个开关都是关闭的状态.要通过 ...

  8. Loj #3042. 「ZJOI2019」麻将

    Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...

  9. 【LOJ】#3046. 「ZJOI2019」语言

    LOJ#3046. 「ZJOI2019」语言 先orz zsy吧 有一个\(n\log^3n\)的做法是把树链剖分后,形成logn个区间,这些区间两两搭配可以获得一个矩形,求矩形面积并 然后就是对于一 ...

随机推荐

  1. Spark 基于物品的协同过滤算法实现

    J由于 Spark MLlib 中协同过滤算法只提供了基于模型的协同过滤算法,在网上也没有找到有很好的实现,所以尝试自己实现基于物品的协同过滤算法(使用余弦相似度距离) 算法介绍 基于物品的协同过滤算 ...

  2. 手机端页面自适应解决方案—rem布局(该方案目前已过时)

    转自:https://segmentfault.com/a/1190000004705207 相信很多刚开始写移动端页面的同学都要面对页面自适应的问题,当然解决方案很多,比如:百分比布局,弹性布局fl ...

  3. 在xampp集成环境下使用 php 连接oracle

    今天搞了大半天,终于成功了. 1. 首先需要让xampp支持oracle,直接按这个网页上说的做就行.http://nimal.info/blog/2009/activate-oracle-on-xa ...

  4. Les13 性能管理

    目标 使用Oracle Enterprise Manager监视性能 使用自动内存管理(AMM) 使用内存指导调整内存缓冲区的大小 查看与性能相关的动态视图 排除无效和不可用对象产生的故障 性能监视 ...

  5. 《OpenCL编程指南》之 与Direct3D互操作

    介绍OpenCL与D3D 10之间的互操作. 1.初始化OpenCL上下文实现Direct3D互操作 OpenCL共享由pragma cl_khr_d3d10_sharing启用: #pragma O ...

  6. VS2013 VC++的.cpp文件调用CUDA的.cu文件中的函数

    CUDA 8.0在函数的调用中方便的让人感动.以下是从网上学到的VC++的.cpp文件调用CUDA的.cu文件中的函数方法,和一般的VC++函数调用的方法基本没差别. 使用的CUDA版本为CUDA 8 ...

  7. DXVA2解码数据用texture纹理渲染

    FFmpeg DXVA2解码得到的数据使用surface来承载的,surface限制很多,如果能用纹理来渲染的话,那我们就可以充分开发D3D,比如可以用坐标变换来实现电子放大的功能,还可以用坐标变换来 ...

  8. nyoj20——有向无环图深搜模板

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市, ...

  9. iOS UI-popoverController

    一.简单介绍 1.什么是UIPopoverController 是iPad开发中常见的一种控制器(在iPhone上不允许使用) 跟其他控制器不一样的是,它直接继承自NSObject,并非继承自UIVi ...

  10. laravel中设置表单的方式,以及获取表单的提交的数据