洛谷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\)片雪花 ...
随机推荐
- MaskRCNN 奔跑自己的数据
import os import sys import random import math import re import time import numpy as np import cv2 i ...
- ant 节点和属性
任务和javac命令是相似,它编译两种类型的java文件1)没有被编译的java文件2)曾经编译过,但是class文件版本和当前对应的java文件版本不匹配的java文件. 1)javac命令支持的参 ...
- C之推栈溢出原因
https://blog.csdn.net/weixin_36194037/article/details/78871468
- Python29之字符str与字节bytes
详解见这位大神:https://www.cnblogs.com/xiaobingqianrui/p/9870480.html 实际上字符串和字节之间的转换过程,就是编码解码的过程,我们必须显示的指定编 ...
- ~postman使用Runner
1.准备参数的.text文件. postman支持三种参数的方式,分别为.text文件,.csv文件,json文件.此处使用.text文件.编码格式使用utf-8 2.替换请求参数 3.设置Runne ...
- AVR单片机教程——开发板介绍
本教程使用EasyElectronics开发板: EasyElectronics是一款基于AVR单片机的开发板.AVR单片机是基于改进的哈佛架构.8~32位的一系列RISC微控制器,最初由Atmel公 ...
- pyrhon 第一个小购物车例子
product_list=[[],[],[],[]] shopping_list=[] salary = input("请输入你的工资:") if salary.isdigit() ...
- NIO堆外内存与零拷贝
重点: 1.0拷贝需要系统支持. 普通内存模型: java线程内存 --> 操作系统内存 --> 硬盘 直接内存模型: java --> 操作系统内存 --> 硬盘 两者对比, ...
- 一行代码实现Vue微信支付,无需引用wexin-sdk库,前后端分离HTML微信支付,无需引用任何库
前后端分离项目实现微信支付的流程: 1:用户点击支付 2:请求服务端获取支付参数 3:客户端通过JS调起微信支付(微信打开的网页) * 本文主要解决的是第3步,视为前两步已经完成,能正确拿到支付参数, ...
- What is Verbose Garbage Collection (verbosegc) and How do I Enable it on WebLogic
问题描述: What is Verbose Garbage Collection (verbosegc) and How do I Enable it on WebLogic 问题分析: 通过添加gc ...