和Leo一起做爱线段树/数学的好孩子之[HAOI2012]高速公路

Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站。

Y901高速公路是一条由N-1段路以及N个收费站组成的东西向的链,我们按照由西向东的顺序将收费站依次编号为1~N,从收费站i行驶到i+1(或从i+1行驶到i)需要收取Vi的费用。高速路刚建成时所有的路段都是免费的。

政府部门根据实际情况,会不定期地对连续路段的收费标准进行调整,根据政策涨价或降价。

无聊的小A同学总喜欢研究一些稀奇古怪的问题,他开车在这条高速路上行驶时想到了这样一个问题:对于给定的l,r(l< r),在第l个到第r个收费站里等概率随机取出两个不同的收费站a和b,那么从a行驶到b将期望花费多少费用呢?

自从上次在树上搞了这个操作之后
我觉得不是特别难了
我们思考暴力这个期望:
E=∑i=lr∑j=l+1rDis(i,j)Cr−l+12E=\frac{\sum_{i=l}^{r}\sum_{j=l+1}^{r}Dis(i,j)}{C_{r-l+1}^{2}}E=Crl+12i=lrj=l+1rDis(i,j)
我们拆开这个式子
发现贡献是:
∑i=lrWi(r−i+1)(l−i+1)\sum_{i=l}^{r}W_{i}(r-i+1)(l-i+1)i=lrWi(ri+1)(li+1)
暴力拆开:
(r−l+1−r∗l)∗Wi+(r+l)∗Wi∗i−Wi∗i∗i(r-l+1-r*l)*W_{i}+(r+l)*W_{i}*i-W_{i}*i*i(rl+1rl)Wi+(r+l)WiiWiii
实际上就是维护个区间求和
线段树维护就好了
那么区间加就可以维护了:
维护:
∑i\sum ii∑i2\sum i^{2}i2
完。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define int long long 
#define lc (p<<1)
#define rc (p<<1|1)
const int N=1e5+1000;
inline void read(int &x){
    x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
int a[N];
int GetGCD(int x,int y){
    while(y){
        int tmp=y;
        y=x%y;
        x=tmp;
    }
    return x;
}	
struct Node{
    int lson,rson;
    int sum1;//a[i]
    int sum2;//a[i]*i
    int sum3;//a[i]*i*i
    int sum4;//i
    int sum5;//i*i
    int lazy;
    Node(){
        lson=rson=sum1=sum2=sum3=sum4=sum5=lazy=0;
    }
}T[N<<2];
Node operator + (Node A,Node B){
    Node C;
    C.sum1=A.sum1+B.sum1;
    C.sum2=A.sum2+B.sum2;
    C.sum3=A.sum3+B.sum3;
    C.sum4=A.sum4+B.sum4;
    C.sum5=A.sum5+B.sum5;	
    C.lson=A.lson;
    C.rson=B.rson;
    return C;	
}
struct Segment_Tree{
    inline void PushNow(int p,int val){
            T[p].sum1+=(T[p].rson-T[p].lson+1)*val;
            T[p].sum2+=T[p].sum4*val;
            T[p].sum3+=T[p].sum5*val;
            T[p].lazy+=val;		
    }
    inline void PushDown(int p){
        if(T[p].lazy){
            PushNow(lc,T[p].lazy);
            PushNow(rc,T[p].lazy);
            T[p].lazy=0;
        }
    }
    inline void Build(int p,int l,int r){
        T[p].lson=l;
        T[p].rson=r;
        if(l==r){
            T[p].sum1=a[l];
            T[p].sum2=a[l]*l;
            T[p].sum3=a[l]*l*l;
            T[p].sum4=l;
            T[p].sum5=l*l;
            return;
        }
        int mid=(l+r)>>1;
        Build(lc,l,mid);
        Build(rc,mid+1,r);
        T[p]=T[lc]+T[rc];
    }
    inline void Update(int p,int l,int r,int val){
        if(l<=T[p].lson&&T[p].rson<=r){
            PushNow(p,val);
            return;
        }
        int mid=(T[p].lson+T[p].rson)>>1;
        PushDown(p);
        if(l<=mid)Update(lc,l,r,val);
        if(mid< r)Update(rc,l,r,val);
        T[p]=T[lc]+T[rc];
    }
    Node Query(int p,int l,int r){
        if(l<=T[p].lson&&T[p].rson<=r){
            return T[p];
        }
        int mid=(T[p].lson+T[p].rson)>>1;
        PushDown(p);
        Node ret;
        if(l<=mid)ret=ret+Query(lc,l,r);
        if(mid <r)ret=ret+Query(rc,l,r);
        return ret;
    }
}Tree;
int n,Q;
char S[10];
signed main(){
// 	freopen("test.in","r",stdin);
    read(n);
    read(Q);
    Tree.Build(1,1,n);
    while(Q--){
        scanf("%s",S+1);
        if(S[1]=='C'){
            int l,r,v;
            read(l);
            read(r);
            r--;
            read(v);
            Tree.Update(1,l,r,v);
        }
        else{
            int l,r;
            read(l);
            read(r);
            r--;
            Node Now=Tree.Query(1,l,r);
            int son=(r-l+1-r*l)*Now.sum1+(r+l)*Now.sum2-Now.sum3;
//			cout<<Now.sum1<<" "<<Now.sum2<<" "<<Now.sum3<<'\n';
            int mother=(r-l+2)*(r-l+1)/2;
            int GCD=GetGCD(son,mother);
            cout<<son/GCD<<"/"<<mother/GCD<<'\n';
        }
    }
}

转载于:https://www.cnblogs.com/Leo-JAM/p/10079066.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值