[ZJOI2019]线段树
题目大意
一开始有一棵线段树,然后有一个操作序列,问执行这个操作序列的所有子集时线段树上有标记的节点个数和。
题解
其实我们把它除以\(2^m\)后发现就是有标记节点的期望个数。
然后套路的根据期望的线性性,我们要统计所有点有标记的概率和。
然后我们来讨论一些情况:
1、当前节点和修改区间没有交且当前节点的父亲节点也没有交,那么这个点的标记就不会动。
2、当前节点被修改区间包含且父亲节点也被包含,那根本碰不到这个节点,也不会动。
3、当前节点被修改区间包含且父亲节点没有被包含,那么这个节点一定会有标记。
4、当前节点和修改区间有交但不包含,那么这个点一定没有标记。
5、这个点和修改区间没有交但是父亲有,那么这个点有没有标记取决于这个点的祖先节点(包括自己)有没有标记。
我们观察到第5种情况需要考虑到祖先节点是否有标记,所以我们设一个\(f\)表示这个点有标记的概率,\(g\)表示这个点的祖先节点有(包括自己)标记的概率。
对于第一种情况不做讨论。
对于第二种情况,\(f\)是没有变化的,\(g=g*0.5+0.5\)。
对于第三种情况,\(f=f*0.5+0.5\ g=g*0.5+0.5\);
对于第四种情况\(f=f*0.5\ g=g*0.5\)。
对于第五种情况\(f=f*0.5+g*0.5\ g=g*0.5+g*0.5\)。
这些都可以按照线段树的操作去维护。
代码
#include<iostream>
#include<cstdio>
#define ls tr[cnt].l
#define rs tr[cnt].r
#define N 100009
using namespace std;
typedef long long ll;
const int mod=998244353;
ll now,inv2;
int tot,n,m,rot;
inline int rd(){
int x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
inline ll power(ll x,ll y){
ll ans=1;
while(y){if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;}
return ans;
}
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
struct node{
int l,r;
ll multag,addtag,f,g,sum;
}tr[N<<1];
inline void pushup(int cnt){(tr[cnt].sum=tr[ls].sum+tr[rs].sum+tr[cnt].f)%=mod;}
inline void gx(int cnt){
tr[cnt].f=(tr[cnt].g+tr[cnt].f)*inv2%mod;
pushup(cnt);
}
inline void gan(int cnt,ll x,ll y){
MOD(tr[cnt].g=tr[cnt].g*x%mod+y);
tr[cnt].multag=tr[cnt].multag*x%mod;
MOD(tr[cnt].addtag=tr[cnt].addtag*x%mod+y);
}
inline void pushdown(int cnt){
if(tr[cnt].multag==1&&!tr[cnt].addtag)return;
gan(ls,tr[cnt].multag,tr[cnt].addtag);
gan(rs,tr[cnt].multag,tr[cnt].addtag);
tr[cnt].multag=1;tr[cnt].addtag=0;
}
void upd(int cnt,int l,int r,int L,int R){
if(l>=L&&r<=R){
MOD(tr[cnt].f=tr[cnt].f*inv2%mod+inv2);
gan(cnt,inv2,inv2);pushup(cnt);return;
}
tr[cnt].f=tr[cnt].f*inv2%mod;
tr[cnt].g=tr[cnt].g*inv2%mod;
int mid=(l+r)>>1;
pushdown(cnt);
if(mid>=L)upd(ls,l,mid,L,R);
if(mid<R)upd(rs,mid+1,r,L,R);
if(mid<L)gx(ls);if(mid>=R)gx(rs);
pushup(cnt);
}
void build(int &cnt,int l,int r){
cnt=++tot;
tr[cnt].multag=1;
if(l==r)return;
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
}
int main(){
n=rd();m=rd();inv2=power(2,mod-2);
build(rot,1,n);
int l,r,opt;now=1;
for(int i=1;i<=m;++i){
opt=rd();
if(opt==1){
l=rd();r=rd();
upd(rot,1,n,l,r);
MOD(now=now+now);
}
else printf("%lld\n",tr[rot].sum*now%mod);
}
return 0;
}
[ZJOI2019]线段树的更多相关文章
- Luogu P5280 [ZJOI2019]线段树
送我退役的神题,但不得不说是ZJOIDay1最可做的一题了 先说一下考场的ZZ想法以及出来后YY的优化版吧 首先发现每次操作其实就是统计出增加的节点个数(原来的不会消失) 所以我们只要统计出线段树上每 ...
- Luogu5280 ZJOI2019线段树(线段树)
容易发现相当于求2m种操作序列所得的每种线段树tag数量之和.显然考虑每个点的贡献,也即有多少种方案会使该点上有tag.可以将点分为四类: 1.修改时被经过且有儿子被修改的节点 2.修改时被经过且没有 ...
- P5280 [ZJOI2019]线段树
题目链接:洛谷 题目描述:[比较复杂,建议看原题] 这道题太神仙了,线段树上做树形dp. 根据树形dp的套路,都是按照转移的不同情况给节点分类.这里每次modify的时候对于节点的影响也不同,所以我们 ...
- 【洛谷5280】[ZJOI2019] 线段树(线段树大力分类讨论)
点此看题面 大致题意: 给你一棵线段树,两种操作.一种操作将每棵线段树复制成两个,然后在这两个线段树中的一个上面进行\(Modify(l,r)\).另一种操作询问所有线段树的\(tag\)总和. 大力 ...
- 洛谷P5280 [ZJOI2019]线段树
https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...
- Luogu5280 [ZJOI2019] 线段树 【线段树】
题目分析: 这题除了分类讨论就没啥了... 容易发现问题实际就是所有操作选和不选按顺序执行的所有答案和.考虑每个点在多少种情况下会有tag. 那么,考虑新插入一个[l,r],所有有交集的点都会被清空, ...
- [Luogu5280][ZJOI2019]线段树(线段树+DP)
https://www.luogu.org/blog/Sooke/solution-p5280 首先想到对线段树上每个点分别维护有多少棵线段树在它上有标记(f[]),然后想到对于每个操作,根据转移的不 ...
- 【LuoguP5280】[ZJOI2019] 线段树
题目链接 题目描述 略 Sol 显然不能直接暴力模拟. 观察这个东西本质在干什么,就是某一次操作可能进行可能不进行,然后求所有情况下被标记节点总数. 这个显然可以转化为概率问题,每次有二分之一的概率进 ...
- 洛谷 P5280 - [ZJOI2019]线段树(线段树+dp,神仙题)
题面传送门 神仙 ZJOI,不会做啊不会做/kk Sooke:"这八成是考场上最可做的题",由此可见 ZJOI 之毒瘤. 首先有一个非常显然的转化,就是题目中的"将线段树 ...
随机推荐
- asp.net easyui 动态绑定下拉框
前台: <title>标题</title> <link href="EasyUi_v1.3.4/easyui/themes/default/easyui.css ...
- Python机器学习实践:决策树判别汽车金融违约用户
文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 转自 | 法纳斯特(公众号ID:walker398) 作者 | 小F 决策树呈树形结构,是一种基本的回 ...
- 复活广州.net俱乐部
上个月张队长在深圳搞了一场活动,我们广州这边的.net粉丝也去了几个,我刚好有辆破车,于是我们一车会合后出发去深圳参加活动了,和大家在车上的交流使我感触良多.只说几点和本文相关的: .net在中国的生 ...
- mpvue学习笔记-之微信小程序数据请求封装
简介 美团出品的mpvue已经开源出来很久了,一直说要进行一次实践,这不最近一次个人小程序开发就用上了它. 看了微信官方的数据请求模块--request,对比了下get和post请求的代码,发现如果在 ...
- 基于Netty 实现简单的私有协议
原文链接 基于Netty 实现简单的私有协议 代码仓库地址 基于Netty 实现简单的私有协议 在学习了Netty的不同的编码器和解码器之后,我们可以通过编解码器实现简单的自定义协议,这个自定义的协议 ...
- 将对象xml序列化和反序列化
//将一个对象按XML序列化的方式写入到一个文件,使用的默认的UTF8编码格式 //o为要序列化的对象 //path保存文件的路径 public static object _lockObj=new ...
- windows docker redis
拉取docker docker pull hub.c.163.com/library/redis:latest 启动docker docker run -p 6379:6379 -d hub.c.16 ...
- IDEA Can't Update No tracked branch configured for branch master or the branch doesn't exist.
IDEA Can't Update No tracked branch configured for branch master or the branch doesn't exist.To make ...
- 重大变革即将来临 5G CPE会替代光纤入户吗?
导读 从国内的新闻报道上我们可以看到,从2018年下半年开始各大重要活动.春晚直播等,都宣布已经使用5G网络.既然支持5G网络的终端都还没有正式上市,那么5G网络是如何使用的呢?答案是5G CPE设备 ...
- 网络流24题 P1251 餐巾计划问题 拆点
题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送 ...