P4915 帕秋莉的魔导书(动态开点线段树)
题目背景
帕秋莉有一个巨大的图书馆,里面有数以万计的书,其中大部分为魔导书。
题目描述
魔导书是一种需要钥匙才能看得懂的书,然而只有和书写者同等或更高熟练度的人才能看得见钥匙。因此,每本魔导书都有它自己的等级 ai,同时它也有自己的知识程度为 wi,现在我们想要知道,一个等级为 bi的生物(...),可以从这些魔导书中得到多少知识。
然而不幸的是,每个生物并不知道自己确切的等级,只有一个等级的大致范围,你需要计算出这个生物获得知识程度的期望值。
输入格式
第一行两个正整数 n,m 代表起始书的个数,以及操作的个数。
以下 n 行,每行两个正整数 ai 和 wi,代表每本书的等级以及知识程度。
接下来的 m 行,每行 2 或 3 个正整数。
操作 1:格式:1 x y。含义:求等级为 [x,y] 的生物能获得的期望知识程度。
操作 2:格式:2 x y。含义:图书馆又收入了一本等级为 x,知识程度为 y 的魔导书。
输出格式
输出包含若干行实数,即为所有操作 1 的结果,答案保留四位小数。
输入输出样例
输入 #1
5 5
1 1
2 1
3 1
4 1
5 1
1 2 5
1 1 5
1 3 5
2 1 5
1 1 2
输出 #1
3.5000
3.0000
4.0000
6.5000
说明/提示
对于 30% 的数据,保证 1 <=所有输入的数字 ≤10^3。
对于 100% 的数据,保证 1≤n,m≤10^5,对于其他数字,保证在 32 位带符号整数范围内(保证运算中所有的数均在 −2^63∼2^63−1 内)。
分析
首先,题目让我们求的是这个柿子
$\displaystyle\sum_{i=x}^{y} tot[i] $ /(y-x+1)
即 \(\displaystyle\sum_{i=x}^{y} tot[i] \over y-x+1\)
tot[i]为i这个等级能看到的知识程度的总和。
我们可以以等级为区间,知识程度为权值。
那不就是区间和除以区间长度了吗?
看到区间和,我们就可以想到用线段树来维护。
但等级可能会达到2^32-1,所以我们考虑一下动态开点或者离散化(蒟蒻我不会写)
当新添一本书后,等级大于他的都可以看到,就相当于从这本书的等级到inf的区间,加上这本书的知识程度。
查询操作,就是区间和除以区间长度就OK了。
一定要注意开 long long(不开long long 见祖宗)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const int inf = 2147483536;
int n,m,x,y,opt,root,tot;
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
return s * w;
}
struct Tree
{
struct node{
int lc,rc;
LL sum,add;
}tr[10000010];
void down(int o,int l,int r)//下放操作
{
if(tr[o].add)
{
int mid = (l+r)>>1;
if(!tr[o].lc) tr[o].lc = build();//如果没有子节点就新建一个
if(!tr[o].rc) tr[o].rc = build();
tr[tr[o].lc].add += tr[o].add;//正常的下放操作
tr[tr[o].rc].add += tr[o].add;
tr[tr[o].lc].sum += 1LL * tr[o].add * (mid-l+1);
tr[tr[o].rc].sum += 1LL * tr[o].add * (r-mid);
tr[o].add = 0;
}
}
int build()//新建一个节点
{
tot++;
tr[tot].lc = tr[tot].rc = tr[tot].sum = 0;
return tot;
}
void insert(int root,int L,int R,int x,int y,int val)//区间修改
{
if(x <= L && y >= R)
{
tr[root].add += val;
tr[root].sum +=1LL * val * (R-L+1);
return;
}
int mid = (L+R)>>1;
down(root,L,R);//下放标记
if(x <= mid)
{
if(!tr[root].lc) tr[root].lc = build();//一定要新开节点,不然就会RE
insert(tr[root].lc,L,mid,x,y,val);
}
if(y > mid)
{
if(!tr[root].rc) tr[root].rc = build();
insert(tr[root].rc,mid+1,R,x,y,val);
}
tr[root].sum = tr[tr[root].lc].sum + tr[tr[root].rc].sum;//up操作
}
LL ask(int root,int L,int R,int x,int y)//区间和
{
LL ans = 0;
if(x <= L && y >= R){return tr[root].sum;}
int mid = (L+R)>>1;
down(root,L,R);
if(!tr[root].lc) tr[root].lc = build();
if(!tr[root].rc) tr[root].rc = build();
if(x <= mid) ans += ask(tr[root].lc,L,mid,x,y);
if(y > mid) ans += ask(tr[root].rc,mid+1,R,x,y);
return ans;
}
}tree;
int main()
{
n = read(); m = read();
root = tree.build();
for(int i = 1; i <= n; i++)
{
x = read(); y = read();
tree.insert(root,1,inf,x,inf,y);//从x到inf区间加y
}
for(int i = 1; i <= m; i++)
{
opt = read(); x = read(); y = read();
if(opt == 1)
{
LL tmp = tree.ask(root,1,inf,x,y);
double ans = (double) tmp / (double)(y-x+1);
printf("%.4lf\n",ans);
}
if(opt == 2)
{
tree.insert(root,1,inf,x,inf,y);
}
}
return 0;
}
P4915 帕秋莉的魔导书(动态开点线段树)的更多相关文章
- P4915 帕秋莉的魔导书
题目链接 题意分析 当前等级为\(x\)的魔法书会对等级在\([x,inf]\)的所有人造成\(y\)的影响 所以除了求平均值之外 就是区间修改区间求和 需要使用动态开点 + 标记永久化 需要注意的是 ...
- P4910 帕秋莉的手环
题目背景 帕秋莉是蕾米莉亚很早结识的朋友,现在住在红魔馆地下的大图书馆里.不仅擅长许多魔法,还每天都会开发出新的魔法.只是身体比较弱,因为哮喘,会在咏唱符卡时遇到麻烦. 她所用的属性魔法,主要是生命和 ...
- [Luogu] P4910 帕秋莉的手环
题目背景 帕秋莉是蕾米莉亚很早结识的朋友,现在住在红魔馆地下的大图书馆里.不仅擅长许多魔法,还每天都会开发出新的魔法.只是身体比较弱,因为哮喘,会在咏唱符卡时遇到麻烦. 她所用的属性魔法,主要是生命和 ...
- 【Cogs2187】帕秋莉的超级多项式(多项式运算)
[Cogs2187]帕秋莉的超级多项式(多项式运算) 题面 Cogs 题解 多项式运算模板题 只提供代码了.. #include<iostream> #include<cstdio& ...
- cogs 998. [東方S2] 帕秋莉·诺蕾姬
二次联通门 : cogs 998. [東方S2] 帕秋莉·诺蕾姬 交上去后发现自己没上榜 就想着加点黑科技 把循环展开一下 结果WA了.. 万恶的姆Q /* cogs 998. [東方S2] 帕秋莉· ...
- 魔卡少女(cardcaptor)——线段树
题目 [题目描述] 君君是中山大学的四年级学生.有一天在家不小心开启了放置在爸爸书房中的一本古书.于是,君君把放在书中最上面的一张牌拿出来观摩了一下,突然掀起一阵大风把书中的其她所有牌吹散到各地.这时 ...
- 【HZOI2015】帕秋莉的超级多项式
题面 题目分析 超级模板题: 多项式乘法 多项式求逆 多项式开根 多项式求导 多项式求积分 多项式求对数 多项式求自然对数为底的指数函数 多项式快速幂 代码实现 #include<iostrea ...
- COGS2187 [HZOI 2015] 帕秋莉的超级多项式
什么都别说了,咱心态已经炸了... question 题目戳这里的说... 其实就是叫你求下面这个式子的导函数: noteskey 其实是道板子题呢~ 刚好给我们弄个多项式合集的说... 各种板子粘贴 ...
- 洛谷 P4910 帕秋莉的手环 矩阵乘法+快速幂详解
矩阵快速幂解法: 这是一个类似斐波那契数列的矩乘快速幂,所以推荐大家先做一下下列题目:(会了,差不多就是多倍经验题了) 注:如果你不会矩阵乘法,可以了解一下P3390的题解 P1939 [模板]矩阵加 ...
随机推荐
- P4609 建筑师
题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数. 小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同. ...
- Idiomatic Phrases Game(最短路+注意坑点)
Tom is playing a game called Idiomatic Phrases Game. An idiom consists of several Chinese characters ...
- Oracle12C创建scott账户
Oracle12C创建scott账户 具体步骤: 打开SqlPlus 输入用户名和密码用户名:sys口令:sys as sysdba 创建c##scott用户CREATE USER c##scott ...
- ZT:做一个连自己都羡慕的人
当你越来越杰出时,自然有人关注你, 当你越来越有能力时,自然会有人看得起你, 改变自己,你才有自信,梦想才会慢慢的实现. 做最好的自己,懒可以毁掉一个人,勤可以激发一个人! 不要等夕阳西下的时候才对自 ...
- git github仓库
起因 centos 下 git到 github仓 经过 下载git yum install git -y 配置git git config --global user.name "Your ...
- [业界方案]用Jaeger来学习分布式追踪系统Opentracing
[业界方案]用Jaeger来学习分布式追踪系统Opentracing 目录 [业界方案]用Jaeger来学习分布式追踪系统Opentracing 0x00 摘要 0x01 缘由 & 问题 1. ...
- PicGo软件搭配gitee实现图床
1.安装PicGo软件,并配置gitee 1.1安装picGo picGo 安装gitee-uploader 插件 官网下载地址如下:最新版本 可以自行选择版本进行下载,这里我选择了最新的版本进行下载 ...
- [LeetCode]11. 盛最多水的容器(双指针)
题目 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两 ...
- Docker添加TLS认证修复2375端口暴露引发的漏洞
#### 1.环境准备 ```bash# 查看Docker服务器主机名hostnamectl``` ![1582697962553](C:\Users\86176\AppData\Roaming\Ty ...
- Gradle系列之Android Gradle基础配置
原文发于微信公众号 jzman-blog,欢迎关注交流. 通过前面几篇文章学习了 Gradle 基础知识以及 Gradle 插件相关的知识,关于 Gradle 及其插件相关知识请先阅读下面几篇文章: ...