Description

漆黑的晚上,九条可怜躺在床上辗转反侧。难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历。那是一道

基础的树状数组题。给出一个长度为 n 的数组 A,初始值都为 0,接下来进行 m 次操作,操作有两种:
1 x,表示将 Ax 变成 (Ax + 1) mod 2。
2 l r,表示询问 sigma(Ai) mod 2,L<=i<=r
尽管那个时候的可怜非常的 simple,但是她还是发现这题可以用树状数组做。当时非常young 的她写了如下的算
法:

其中 lowbit(x) 表示数字 x 最?的非 0 二进制位,例如 lowbit(5) = 1, lowbit(12) = 4。进行第一类操作的时
候就调用 Add(x),第二类操作的时候答案就是 Query(l, r)。如果你对树状数组比较熟悉,不难发现可怜把树状
数组写错了: Add和Find 中 x 变化的方向反了。因此这个程序在最终测试时华丽的爆 0 了。然而奇怪的是,在
当时,这个程序通过了出题人给出的大样例——这也是可怜没有进行对拍的原因。现在,可怜想要算一下,这个程
序回答对每一个询问的概率是多少,这样她就可以再次的感受到自己是一个多么非的人了。然而时间已经过去了很
多年,即使是可怜也没有办法完全回忆起当时的大样例。幸运的是,她回忆起了大部分内容,唯一遗忘的是每一次
第一类操作的 x的值,因此她假定这次操作的 x 是在 [li, ri] 范围内 等概率随机 的。具体来说,可怜给出了
一个长度为 n 的数组 A,初始为 0,接下来进行了 m 次操作:
1 l r,表示在区间 [l, r] 中等概率选取一个 x 并执行 Add(x)。
2 l r,表示询问执行 Query(l, r) 得到的结果是正确的概率是多少。

Input

第一行输入两个整数 n, m。
接下来 m 行每行描述一个操作,格式如题目中所示。
N<=10^5,m<=10^5,1<=L<=R<=N

Output

对于每组询问,输出一个整数表示答案。如果答案化为最简分数后形如 x/y
,那么你只需要输出 x*y-1 mod 998244353 后的值。(即输出答案模 998244353)。

Sample Input

5 5
1 3 3
2 3 5
2 4 5
1 1 3
2 2 5

Sample Output

1
0
665496236
//在进行完 Add(3) 之后, A 数组变成了 [0, 1, 1, 0, 0]。所以前两次询问可怜的程序答案都是
1,因此第一次询问可怜一定正确,第二次询问可怜一定错误。

数据范围

查询(l,r)从前缀变为了后缀

那么原来是S[r]-s[l-1],变成了S[l-1]-s[r]

原来的区间是[l,r],现在变成了[l-1,r-1]

询问要正确就要求l-1和r的值必须一样

当l=1时

S[r]-s[0]=>s[0]-s[r]=-s[r]

所以此时要正确就必须使1~r的前缀和与r~n的前缀和相同

将查询(l-1,r)用一个点表示

修改[l,r]的一个数,分成几种情况讨论:

1.使询问的值一样的概率:

(1):x属于[1,l-1],y属于[l,r].此时要相同必须要求y不被选中,概率(1-p)

(2):y属于[r+1,n],x属于[l,r].此时同上,x不能被选中

(3):x,y同属于[l,r].x,y都不能被选中,概率(1-2p)

2.使询问的r的前缀和等于后缀和的概率:x为0

(1):y属于[0,l-1].因为[l,r]总会改一个数,所以概率为0

(2):y属于[r+1,n+1].同上

(3):y属于[l,r].要求选中y,概率为p

修改用树套树(二维线段树),外层的树维护第一维坐标,内层的树维护第二维坐标

不过空间不够,要动态开点

如何合并两次修改:假设两次的相同概率分别为p1,p2(以上2种情况统称相同)

显然新的概率为:p1*p2+(1-p1)*(1-p2)

都不相同合起来就相同了

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
lol Mod=;
int size,root[],ch[][],n,m;
int ans,sum[];
int merge(lol x,lol y)
{
return (x*y%Mod+(-x+Mod)*(-y+Mod)%Mod)%Mod;
}
lol qpow(lol x,int y)
{
lol res=;
while (y)
{
if (y&) res=res*x%Mod;
x=x*x%Mod;
y>>=;
}
return res;
}
void update2(int &rt,int l,int r,int L,int R,lol v)
{
if (!rt) rt=++size,sum[rt]=;
if (l>=L&&r<=R)
{
sum[rt]=merge(sum[rt],v);
return;
}
int mid=(l+r)>>;
if (L<=mid) update2(ch[rt][],l,mid,L,R,v);
if (R>mid) update2(ch[rt][],mid+,r,L,R,v);
}
void update1(int rt,int l,int r,int L,int R,int LL,int RR,lol v)
{
if (l>=L&&r<=R)
{
update2(root[rt],,n+,LL,RR,v);
return;
}
int mid=(l+r)>>;
if (L<=mid) update1(rt<<,l,mid,L,R,LL,RR,v);
if (R>mid) update1(rt<<|,mid+,r,L,R,LL,RR,v);
}
void query2(int rt,int l,int r,int x1)
{
if (!rt) return;
ans=merge(ans,sum[rt]);
if (l==r) return;
int mid=(l+r)>>;
if (x1<=mid) query2(ch[rt][],l,mid,x1);
else query2(ch[rt][],mid+,r,x1);
}
void query1(int rt,int l,int r,int x1,int x2)
{
if (root[rt]) query2(root[rt],,n+,x2);
if (l==r)
return;
int mid=(l+r)>>;
if (x1<=mid) query1(rt<<,l,mid,x1,x2);
else query1(rt<<|,mid+,r,x1,x2);
}
int main()
{int i,opt,l,r;
cin>>n>>m;
for (i=;i<=m;i++)
{
scanf("%d%d%d",&opt,&l,&r);
if (opt==)
{
lol p=qpow(r-l+,Mod-);
if (l>) update1(,,n,,l-,l,r,(-p+Mod)%Mod);
if (r<n) update1(,,n,l,r,r+,n,(-p+Mod)%Mod);
lol pp=p*%Mod;
update1(,,n,l,r,l,r,(-pp+Mod)%Mod);
update1(,,n,,,,l-,);
update1(,,n,,,r+,n+,);
update1(,,n,,,l,r,p);
}
else
{
ans=;
query1(,,n,l-,r);
printf("%d\n",ans);
}
}
}

[ZJOI2017]树状数组的更多相关文章

  1. [BZOJ4785][ZJOI2017]树状数组(概率+二维线段树)

    4785: [Zjoi2017]树状数组 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 297  Solved: 195[Submit][Status ...

  2. 【BZOJ4785】[Zjoi2017]树状数组 树套树(二维线段树)

    [BZOJ4785][Zjoi2017]树状数组 Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一 ...

  3. bzoj4785 [Zjoi2017]树状数组

    Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进 ...

  4. bzoj4785:[ZJOI2017]树状数组:二维线段树

    分析: "如果你对树状数组比较熟悉,不难发现可怜求的是后缀和" 设数列为\(A\),那么可怜求的就是\(A_{l-1}\)到\(A_{r-1}\)的和(即\(l-1\)的后缀减\( ...

  5. LOJ2251 [ZJOI2017] 树状数组【线段树】【树套树】

    题目分析: 对于一个$add$操作,它的特点是与树状数组的查询相同,会给$1$到它自己产生影响,而$query$操作则会途径所有包含它的树状数组点.现在$add$操作具有前向性(不会影响之后的点).所 ...

  6. BZOJ4785 ZJOI2017树状数组(概率+二维线段树)

    可以发现这个写挂的树状数组求的是后缀和.find(r)-find(l-1)在模2意义下实际上查询的是l-1~r-1的和,而本来要查询的是l~r的和.也就是说,若结果正确,则a[l-1]=a[r](mo ...

  7. 【uoj291】 ZJOI2017—树状数组

    http://uoj.ac/problem/291 (题目链接) 题意 一个写错的树状数组有多大的概率与正常树状数组得出的答案一样. Solution 可以发现这个树状数组维护的是后缀和. 所以二维线 ...

  8. BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】

    题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...

  9. 洛谷P3688/uoj#291. [ZJOI2017]树状数组

    传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...

随机推荐

  1. JavaScript(第二十天)【DOM操作表格及样式】

    DOM在操作生成HTML上,还是比较简明的.不过,由于浏览器总是存在兼容和陷阱,导致最终的操作就不是那么简单方便了.本章主要了解一下DOM操作表格和样式的一些知识. 一.操作表格 <table& ...

  2. C语言博客作业--函数嵌套调用

    一.实验作业(6分) 本周作业要求: 选一题PTA题目介绍. 学习工程文件应用,设计实现学生成绩管理系统. 学生成绩管理系统要求 设计一个菜单驱动的学生成绩管理程序,管理n个学生m门考试科目成绩,实现 ...

  3. Alpha冲刺第十一天

    Alpha冲刺第十一天 站立式会议 项目进展 项目进入尾声,主要测设工作完成过半,项目总结也开始进行. 问题困难 项目的困难现阶段主要是测试过程中存在一些"盲点"很难发现或者发现后 ...

  4. 关于collectionView和tableView的两种cell的出列方法的区别

    相信好多人一定会对collectionView和tableView的两种cell出列方法有所疑问,下面以UICollection为例子进行举例说明 假设我们已经创建了一个collectionView, ...

  5. 手把手教你 LabVIEW 串口仪器控制——VISA 驱动下载安装篇

           仪器控制,核心在于 VISA 函数..有些仪器可能不需要 VISA,有自己的 DLL 什么的,我就管不着.        正常情况下,大家安装的 LabVIEW,都是不带 VISA 驱动 ...

  6. 【技巧】Java工程中的Debug信息分级输出接口

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  7. Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1

    摘要: Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1 安装遇到问题请文末留言. 悦动智能公众号:aibbtcom AI这个概念好像突然就 ...

  8. python Django学生管理

    Django 学生管理系统 1. 一对一 班级  模态增加 编辑 <!DOCTYPE html> <html lang="en"> <head> ...

  9. CMDB资产采集

    Agent(方式) 1:服务器每台都需要安装Agent 达到采集速度快,简单:造成性能损耗 获取每台服务器的资产并有返回值:v=subprocess.getoutput('dir')或者ipconfi ...

  10. Windows10 64位系统安装 .NET Framework 3.5

    1)下载NET Framework 3.5 [地址:https://pan.baidu.com/s/1c1FhXLY] 2)编辑NET Framework 3.5.bat ,修改sxs文件存放路径: ...