洛谷P2221 高速公路【线段树】
题目:https://www.luogu.org/problemnew/show/P2221
题意:有n个节点排成一条链,相邻节点之间有一条路。
C u v val表示从u到v的路径上的每条边权值都加val。
Q l r表示在l到r中等概率选择两个城市的路径长度的期望值。
思路:首先期望值的分子肯定是可以选择的方案数也就是$C^2_{r - l + 1}$
分子应该是所有可能的路径和。我们可以通过计算每一条边算了多少次得到。
对于第$i$条边,他的左端点有$(i - l + 1)$种可能,右端点有$(r - i + 1)$种可能。因此这$(i - l + 1)*(r - i + 1)$种路径都包含第$i$条边
所以分子可以表示为$\sum_{l}^{r}(i-l+1)*(r - i + 1) * a[i]$
把含$i$的和不含的都分离出来。可以变为$(r - l + 1-r*l)\sum a[i] + (r + l)\sum i *a[i] - \sum i^2*a[i]$
分别用线段树维护$\sum a[i], \sum i * a[i], \sum i^2 * a[i]$
小trick是$i$和$i^2$之和也可以保存在线段树节点中,维护起来比较方便。
#include<cstdio>
#include<cstdlib>
#include<map>
#include<set>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#include<queue>
#include<iostream> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int, int> pr; int n, m;
const int maxn = 1e5 + ;
struct node{
LL i, a, ia, ii, iia, lazy;
}tree[maxn * ]; void build(int rt, int l, int r)
{
if(l == r){
tree[rt].i = l;
tree[rt].ii = 1ll * l * l;
return;
}
int mid = (l + r) / ;
build(rt << , l, mid);
build(rt << | , mid + , r);
tree[rt].i = tree[rt << ].i + tree[rt << | ].i;
tree[rt].ii = tree[rt << ].ii + tree[rt << | ].ii;
} void pushdown(int rt, int l, int r)
{
if(tree[rt].lazy){
tree[rt << ].lazy += tree[rt].lazy;
tree[rt << | ].lazy += tree[rt].lazy;
int mid = (l + r) / ;
tree[rt << ].a += 1ll * tree[rt].lazy * (mid - l + );
tree[rt << | ].a += 1ll * tree[rt].lazy * (r - mid);
tree[rt << ].ia += 1ll * tree[rt].lazy * tree[rt << ].i;
tree[rt << |].ia += 1ll * tree[rt].lazy * tree[rt << |].i;
tree[rt << ].iia += 1ll * tree[rt].lazy * tree[rt << ].ii;
tree[rt << |].iia += 1ll * tree[rt].lazy * tree[rt << |].ii;
tree[rt].lazy = ;
} } void pushup(int rt)
{
tree[rt].a = tree[rt << ].a + tree[rt << |].a;
tree[rt].ia = tree[rt << ].ia + tree[rt << | ].ia;
tree[rt].iia = tree[rt << ].iia + tree[rt << | ].iia;
} void update(int L, int R, int l, int r, int rt, int val)
{
if(L <= l && R >= r){
tree[rt].a += 1ll * val * (r - l + );
tree[rt].ia += 1ll * val * tree[rt].i;
tree[rt].iia += 1ll * val * tree[rt].ii;
tree[rt].lazy += val;
return;
}
pushdown(rt, l, r);
int mid = (l + r) / ;
if(L <= mid)update(L, R, l, mid, rt << , val);
if(R > mid)update(L, R, mid + , r, rt << | , val);
pushup(rt);
} LL sum1, sum2, sum3;
void query(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r){
sum1 += tree[rt].a;
sum2 += tree[rt].ia;
sum3 += tree[rt].iia;
return;
}
pushdown(rt, l, r);
int mid = (l + r) / ;
if(L <= mid)query(L, R, l, mid, rt << );
if(R > mid)query(L, R, mid + , r, rt << | ); } LL gcd(LL a, LL b)
{
if(!b)return a;
else return gcd(b, a % b);
}
int main()
{
scanf("%d%d", &n, &m);
build(, , n - );
for(int i = ; i < m; i++){
string type;
int l, r;
cin>>type>>l>>r; r--;
if(type[] == 'C'){
int val;
scanf("%d", &val);
update(l, r, , n - , , val);
}
else{
sum1 = sum2 = sum3 = ;
query(l, r, , n - , );
LL fac = (1ll * r - l + - 1ll * r * l) * sum1 + (r + l) * sum2 - sum3;
LL div = 1ll * (r - l + ) * (r - l + ) / ;
// cout<<sum1<<" "<<sum2<<" "<<sum3<<endl;
// cout<<fac<<" "<<div<<endl;
LL g = gcd(fac, div);
fac /= g;
div /= g;
printf("%lld/%lld\n", fac, div);
}
}
return ;
}
洛谷P2221 高速公路【线段树】的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 【洛谷】【线段树】P1471 方差
[题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...
- 【洛谷】【线段树】P1047 校门外的树
[题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...
- 【洛谷】【线段树】P1886 滑动窗口
[题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...
- 【洛谷】【线段树】P3353 在你窗外闪耀的星星
[题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...
- 洛谷P5280 [ZJOI2019]线段树
https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...
- 洛谷 - P1198 - 最大数 - 线段树
https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...
- 洛谷P3374(线段树)(询问区间和,支持单点修改)
洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...
- 洛谷 P2391 白雪皑皑 线段树+优化
题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...
随机推荐
- Tp5.1 管理后台开发纪要
1. tp5.1 对网页是有缓存机制的 E:\phpStudy\PHPTutorial\WWW\NewAdmin\thinkphp\library\think\Template.php 下displa ...
- u盘传输文件时提示过大
(无需格式化U盘) 1.拷贝大文件时提示目标文件系统过大,无法复制 2.查U盘,发现剩余空间足够: 3.分析原因,是由于U盘的格式问题导致的,当期的磁盘格式是FAT32类型的,无拷贝过大的文件: 4. ...
- Python3 - 随便说一下
Ⅰ编程语言基础知识 ⅡPython 语言概述 Ⅰ编程语言基础知识 编程语言总体分以为机器语言.汇编语言.高级语言: 机器语言:计算机硬件能够直接使用的编程语言,二进制的集合,属于低级语言. 汇编语言: ...
- 关于NumPy的常用函数random.randint
np.random.randint(low, high=None, size=None, dtype='l') 该函数作用:用于产生离散均匀分布的整数 low:生成元素的最小值 high:生成元素的值 ...
- 腾讯云开发微信小程序使用体验
主体内容 代码构成 数据:JSON 配置文件 结构:WXML 模版文件 样式:WXSS 页面样式 交互:JS 脚本逻辑文件 云开发 云数据库 云函数 云存储 WXML 是小程序框架设计的一套标签语言, ...
- (转)DMA(Direct Memory Access)
DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...
- 谷歌浏览器调用activex控件方法
原文转自 https://jingyan.baidu.com/article/af9f5a2d0ebe5543140a4596.html activex是由微软开发,所以在支持上,目前原生态支持的只有 ...
- js基本用法
1. 在HTML里面加入JavaScript 方法非常简单,就是通过一对<script></script>标签,然后在标签里面书写代码即可 2. 标签位置 按照以前传统的方法, ...
- 基于【 责任链模式】二 || 网关zuul过滤器封装
一.基于责任链模式封装网关拦截 上一篇文章中已经使用建造者模式对网关拦截进行封装,存在一个问题,在连接器build中,每一个拦截都要进行true判断,代码看起来冗余,下面使用责任链模式封装 1.基于责 ...
- Ext之页面多次请求问题(下拉框发送无关请求)
extjs 下拉框在拉取本地数据,然后又要展示后台数据时,出现过此问题(加载页面,自动发送无关的请求导致后台出现错误日志) { xtype:'combo', id:'state', width:130 ...