[CSP-S模拟测试]:最大值(数学+线段树)
题目背景
$Maxtir$最喜欢最大值。
题目传送门(内部题128)
输入格式
第$1$行输入四个正整数$n,m,q$。
第$2$至$n+1$行中,第$i+1$行输入魔法晶石$i$的三种属性$(x_i,y_i,p_i)$。
接下来$q$行,每行两个正整数$l_i,r_i$,数据保证$[l_i,r_i]$互不包含。
输出格式
输出一行一个正整数$ans$表示答案。
样例
样例输入:
3 3 2
1 1 500000004
2 2 333333336
3 3 1
1 2
2 3
样例输出:
4
数据范围与提示
样例解释:
$500000004\equiv\frac{1}{2}\mod(10^9+7),333333336\equiv\frac{1}{2}\mod(10^9+7)$
最终的魔法阵中的晶石序列可能是
$(\otimes,\otimes,3),(\otimes,2,3),(1,\otimes,3),(1,2,3)$四种,他们的概率分别是$\frac{1}{3},\frac{1}{6},\frac{1}{3},\frac{1}{6}$
两次吸取的能量分别是$(0,3),(2,3),(1,3),(2,3)$,最终的答案是$3\times\frac{1}{3}+5\times\frac{1}{6}+4\times\frac{1}{3}+5\times\frac{1}{6}=4$
数据范围:
对于$100\%$的数据,满足$0\leqslant y_i\leqslant 10^9,1\leqslant q\leqslant n,0\leqslant p_i<10^9+7$

题解
先从$30\%$的部分分入手($10\%$的暴力真的没什么技术含量)。
因为每个魔法阵要取最小值,所以不妨将魔法晶石从大到小排序。
一个魔法晶石能做贡献当且仅当它出现且比它小的都没有出现(当前魔法阵)。
所以考虑这种状态出现的概率,也就是求$P(\max\limits_{i=l}^rv_i\geqslant x)$;化一下式子,即可得到$1-\prod\limits_{i=l}^r1-P(v_i\geqslant x)$。
所以我们可以把小于$x$的数不选的概率乘起来再减去所有数都不选的概率,即$P(v_i\geqslant x)$。
考虑怎么优化,每次更改的贡献就是$1-P(v_i\geqslant y)\rightarrow 1-P(v_i\geqslant x)$。
但是我们可以只考虑$q=\prod\limits_{i=l}^r1-P(v_i\geqslant x)$,这样就可以$\Theta(\log n)$修改了。
想办法利用性质区间互不包含。
将所有区间按左端点排序,就可以实现点和区间的转化了利用线段树优化即可。
时间复杂度:$\Theta(m\log q)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
const int mod=1000000007;
struct rec{int x,y,p;}f[200001];
struct node{int nxt,to;}e[400001];
int head[200001],cnt;
int n,m,q;
int l[200001],r[200001];
long long b[200001];
long long tr[400001],lz[400001];
pair<int,int> p[200001];
long long ans;
bool cmp(rec a,rec b){return a.y<b.y;}
void add(int x,int p)
{
e[++cnt].nxt=head[x];
e[cnt].to=1LL*e[head[x]].to*(1-p)%mod;
head[x]=cnt;
}
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;y>>=1;
}
return res;
}
void pushup(int x){tr[x]=(tr[L(x)]+tr[R(x)])%mod;}
void build(int x,int l,int r)
{
lz[x]=1;
if(l==r){tr[x]=1;return;}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
pushup(x);
}
void pushdown(int x)
{
tr[L(x)]=lz[x]*tr[L(x)]%mod;
tr[R(x)]=lz[x]*tr[R(x)]%mod;
lz[L(x)]=lz[x]*lz[L(x)]%mod;
lz[R(x)]=lz[x]*lz[R(x)]%mod;
lz[x]=1;
}
void change(int x,int l,int r,int L,int R,int w)
{
if(r<L||R<l)return;
if(L<=l&&r<=R){tr[x]=tr[x]*w%mod;lz[x]=lz[x]*w%mod;return;}
int mid=(l+r)>>1;
pushdown(x);
change(L(x),l,mid,L,R,w);
change(R(x),mid+1,r,L,R,w);
pushup(x);
}
void change(int x)
{
if(r[x]<l[x])return;
int res=qpow(1-(e[head[x]].to-b[x])%mod,mod-2);
head[x]=e[head[x]].nxt;
change(1,1,q,l[x],r[x],(1-e[head[x]].to+b[x])*res%mod);
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=m;i++)scanf("%d%d%d",&f[i].x,&f[i].y,&f[i].p);
for(int i=1;i<=q;i++)scanf("%d%d",&p[i].first,&p[i].second);
sort(f+1,f+m+1,cmp);cnt=n;
for(int i=1;i<=n;i++){e[i].to=1;head[i]=i;}
for(int i=1;i<=m;i++)add(f[i].x,f[i].p);
for(int i=1;i<=n;i++)b[i]=e[head[i]].to;
int fl=1,fr=0;
for(int i=1;i<=n;i++)
{
while(fl<=fr&&p[fl].second<i)fl++;
while(p[fr+1].first<=i&&fr<q)fr++;
l[i]=fl;r[i]=fr;
}
build(1,1,q);
for(int i=m,j;i;i=j)
{
for(j=i;f[i].y==f[j].y&&j;j--)change(f[j].x);
ans=(ans+tr[1]*(f[i].y-f[j].y))%mod;
}
ans=(1LL*f[m].y*q-ans)%mod;
printf("%d\n",(ans+mod)%mod);
return 0;
}
rp++
[CSP-S模拟测试]:最大值(数学+线段树)的更多相关文章
- [CSP-S模拟测试]:Weed(线段树)
题目描述 $duyege$的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹.为了查出真相,$duyege$准备修好电脑之后再进行一次金坷垃的模拟实验.电脑上面有若干层金坷垃,每次只能在上面撒上一层高度 ...
- [CSP-S模拟测试]:椎(线段树维护区间最值和单调栈)
题目描述 虽不能至,心向往之. $Treap=Tree+Heap$ 椎$=$树$+$堆 小$\pi$学习了计算机科学中的数据结构$Treap$. 小$\pi$知道$Treap$指的是一种树. 小$\p ...
- [CSP-S模拟测试]:光线追踪(线段树)
题目背景 初中时的乔猫试着组建了$NEWorld$开发组,可是不久之后却因为合作上的问题(和乔猫工程水平差,代码混乱的问题),开发组成员之间常常产生矛盾,关系越来越不如以前......一年下来,受到长 ...
- [CSP-S模拟测试]:bird(线段树优化DP)
题目传送门(内部题89) 输入格式 第一行两个数$n$和$k$,分别表示小鸟的只数和$R$装弹时间.接下来$n$行,每行两个数$l,r$表示$n$只小鸟初始时的头和尾的$x$坐标. 输出格式 输出一个 ...
- [CSP-S模拟测试]:string(线段树)
题目描述 给定一个由小写字母组成的字符串$s$. 有$m$次操作,每次操作给定$3$个参数$l,r,x$. 如果$x=1$,将$s[l]~s[r]$升序排序: 如果$x=0$,将$s[l]~s[r]$ ...
- [CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)
题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j ...
- [CSP-S模拟测试]:旅行(数学+线段树)
题目传送门(内部题12) 输入格式 第一行,一个整数$n$,代表树的点数.第二行,$n$个整数,第$i$个整数是$B_i$,描述排列$B$.接下来$n−1$行,每行两个整数$u,v$,描述一条树边$( ...
- 【10.6校内测试】【小模拟】【hash+线段树维护覆盖序列】
一开始看到题就果断跳到T2了!!没想到T2才是个大坑,浪费了两个小时QAQ!! 就是一道小模拟,它怎么说就怎么走就好了! 为什么要用这么多感叹号!!因为统计答案要边走边统计!!如果每个数据都扫一遍20 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
随机推荐
- EM 算法(三)-GMM
高斯混合模型 混合模型,顾名思义就是几个概率分布密度混合在一起,而高斯混合模型是最常见的混合模型: GMM,全称 Gaussian Mixture Model,中文名高斯混合模型,也就是由多个高斯分布 ...
- Tomcat Connector(BIO, NIO, APR)三种运行模式(转)
Tomcat支持三种接收请求的处理方式:BIO.NIO.APR . BIO 阻塞式I/O操作即使用的是传统 I/O操作,Tomcat7以下版本默认情况下是以BIO模式运行的,由于每个请求都要创建一个线 ...
- ion-icon
观察默认的使用 关于Ion-icon 图标的自定义,首先,看一看默认内置的图标的显示,是怎么来的 可以看到默认的路径为:/svg/ios-xxx.svg 自定义实现 那么这种路径是哪里来的,明显是an ...
- 15 Python之内置函数
思维导图: https://www.processon.com/mindmap/5c10cb5ee4b0090a2c9db92f 1. 匿名函数统一的名字是:<lambda> 使用场景: ...
- js之运算符(算术运算符)
Javascript中的运算符大多是由标点符号少数由关键字表示.可以根据其操作数的个数进行分类.大多数运算符是一个二元运算符,将两个表达式合成一个比较复杂的表达式.还有需要注意的一点是运算符的优先级, ...
- jQuery效果--淡入和淡出
jQuery Fading 方法 通过 jQuery,您可以实现元素的淡入淡出效果. jQuery 拥有下面四种 fade 方法: fadeIn() fadeOut() fadeToggle() fa ...
- Label 自适应文本(StoryBoard/xib)
To make your label automatically resize height you need to do following: Set layout constrains for l ...
- 关于fastJson的几个问题
1.将对象中为null的属性也给序列化出来 可以使用SerializaerFeature实现 JSON.toJSONString(gas, SerializerFeature.WriteMapNull ...
- 17种常用的JS正则表达式 非负浮点数 非负正数
<input type='text' id='SYS_PAGE_JumpPage' name='SYS_PAGE_JumpPage' size='3' maxlength='5' onkeyup ...
- shell 实用脚本
功能 将当前目录下文件拷贝至另一目录下,且拷贝前先备份 #!/bin/sh #脚本功能 #覆盖文件前先备份 cfsuffix=$(date +%Y%m%d); #备份文件后缀 ]; then #输入参 ...