题目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 高速公路【线段树】的更多相关文章

  1. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  2. 【洛谷】【线段树】P1471 方差

    [题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...

  3. 【洛谷】【线段树】P1047 校门外的树

    [题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...

  4. 【洛谷】【线段树】P1886 滑动窗口

    [题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...

  5. 【洛谷】【线段树】P3353 在你窗外闪耀的星星

    [题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...

  6. 洛谷P5280 [ZJOI2019]线段树

      https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...

  7. 洛谷 - P1198 - 最大数 - 线段树

    https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...

  8. 洛谷P3374(线段树)(询问区间和,支持单点修改)

    洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...

  9. 洛谷 P2391 白雪皑皑 线段树+优化

    题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...

随机推荐

  1. 【转】linux卸载mysql

    查看是否安装了MySQL执行命令rpm -qa | grep mysql 执行过程[root@localhost ~]# rpm -qa | grep mysqlmysql-community-lib ...

  2. golang之格式化fmt.Printf

    当使用fmt包打印一个数值时,我们可以用%d.%o或%x参数控制输出的进制格式,就像下面的例子: o := 0666 fmt.Printf("%d %[1]o %#[1]o\n", ...

  3. Scala 面向对象编程之继承

    extends关键字 // Scala中,让子类继承父类,与Java一样,也是使用extends关键字 // 继承就代表,子类可以从父类继承父类的field和method:然后子类可以在自己内部放入父 ...

  4. spring的事务解决方案之@Transactional注解

    首先此注解位于 org.springframework.transaction.annotation 这个包路径下面, 事务有两种类别,一种是编程式事务,另一种是声明式事务,显然此注解是声明式事务,这 ...

  5. Spring Boot学习随记

    由于早年在管理领域耕耘了一段时间,完美错过了Spring的活跃期, 多少对这个经典的技术带有一种遗憾的心态在里面的, 从下面的我的生涯手绘图中大概可以看出来我的经历. 最近由于新介入到了工业数字化领域 ...

  6. AQS独占式同步队列入队与出队

    入队 Node AQS同步队列和等待队列共用同一种节点结构Node,与同步队列相关的属性如下. prev 前驱结点 next 后继节点 thread 入队的线程 入队节点的状态 INITIAl 0 初 ...

  7. jquery easyui form表单一开始就自动启用验证了,修改为form提交的时候在开启验证

    <form method="post" action="<%=path %>" class="easyui-form" d ...

  8. entity-framework-core – 实体框架核心RC2表名称复数

    参考地址:https://docs.microsoft.com/zh-cn/ef/core/modeling/relational/tables http://www.voidcn.com/artic ...

  9. 编写Postgres扩展之四:测试

    原文:http://big-elephants.com/2015-11/writing-postgres-extensions-part-iv/ 编译:http://big-elephants.com ...

  10. Psychedelic therapy

    Psychedelic therapy Psychedelic therapy早期在美国应该取得了相当大的成功,方法是在给予受试者充分的心理准备后,一次性运用极高剂量的LSD(0.3−0.6毫克),试 ...