BZOJ 2752: [HAOI2012]高速公路(road)

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 1463  Solved: 550
[Submit][Status][Discuss]

Description

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将期望花费多少费用呢?

Input


第一行2个正整数N,M,表示有N个收费站,M次调整或询问
接下来M行,每行将出现以下两种形式中的一种
C l r v 表示将第l个收费站到第r个收费站之间的所有道路的通行费全部增加v
Q l r   表示对于给定的l,r,要求回答小A的问题
所有C与Q操作中保证1<=l<r<=N

Output

对于每次询问操作回答一行,输出一个既约分数
若答案为整数a,输出a/1

Sample Input

4 5
C 1 4 2
C 1 2 -1
Q 1 2
Q 2 4
Q 1 4

Sample Output

1/1
8/3
17/6

HINT

数据规模

所有C操作中的v的绝对值不超过10000

在任何时刻任意道路的费用均为不超过10000的非负整数

所有测试点的详细情况如下表所示

Test N M

1 =10 =10

2 =100 =100

3 =1000 =1000

4 =10000 =10000

5 =50000 =50000

6 =60000 =60000

7 =70000 =70000

8 =80000 =80000

9 =90000 =90000

10 =100000 =100000

Source


线段树+期望+gcd

期望定义点此传送

在此三模xxy大佬 

详解见此大佬博客

Orz xxy

Orz xxy

Orz xxy

屠龙宝刀点击就送

#include <ctype.h>
#include <cstdio>
#define N 200020

typedef long long LL;
void read(LL &x)
{
    x=0;
    bool f=0;
    register char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=1;
    for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
    x=f?(~x)+1:x;
}
LL ans1,ans2,ans3,p1[N],p2[N],p3[N],n,m;
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
struct typetree
{
    LL l,r,mid;
    LL sum1,sum2,sum3,flag;
    typetree *ch[2];
    typetree ()
    {
        ch[0]=ch[1]=NULL;
        sum1=sum2=sum3=flag=0;
    }
}*root=new typetree;
class type
{
    private:
        inline void pushup(typetree *&k)
        {
            k->sum1=k->ch[0]->sum1+k->ch[1]->sum1;
            k->sum2=k->ch[0]->sum2+k->ch[1]->sum2;
            k->sum3=k->ch[0]->sum3+k->ch[1]->sum3;
        }
        inline void pushdown(typetree *&k)
        {
            if(k->l==k->r) return;
            k->ch[0]->flag+=k->flag;
            k->ch[1]->flag+=k->flag;
            k->ch[0]->sum1+=k->flag*(p1[k->ch[0]->r]-p1[k->ch[0]->l-1]);
            k->ch[0]->sum2+=k->flag*(p2[k->ch[0]->r]-p2[k->ch[0]->l-1]);
            k->ch[0]->sum3+=k->flag*(p3[k->ch[0]->r]-p3[k->ch[0]->l-1]);
            k->ch[1]->sum1+=k->flag*(p1[k->ch[1]->r]-p1[k->ch[1]->l-1]);
            k->ch[1]->sum2+=k->flag*(p2[k->ch[1]->r]-p2[k->ch[1]->l-1]);
            k->ch[1]->sum3+=k->flag*(p3[k->ch[1]->r]-p3[k->ch[1]->l-1]);
            k->flag=0;
        }
    public:
        void haha(){build(root,1,n-1);}
        void build(typetree *&k,LL l,LL r)
        {
            k=new typetree;
            k->l=l;k->r=r;
            if(l==r) return;
            k->mid=(l+r)>>1;
            build(k->ch[0],l,k->mid);
            build(k->ch[1],k->mid+1,r);
        }
        void query(typetree *&k,LL l,LL r,LL L,LL R)
        {
            if(L<=l&&r<=R)
            {
                ans1+=k->sum1;
                ans2+=k->sum2;
                ans3+=k->sum3;
                return;
            }
            if(k->flag) pushdown(k);
            if(L<=k->mid) query(k->ch[0],l,k->mid,L,R);
            if(R>k->mid) query(k->ch[1],k->mid+1,r,L,R);
            pushup(k);
        }
        void plus(typetree *&k,LL l,LL r,LL L,LL R,LL v)
        {
            if(L<=l&&r<=R)
            {
                k->flag+=v;
                k->sum1+=v*(p1[r]-p1[l-1]);
                k->sum2+=v*(p2[r]-p2[l-1]);
                k->sum3+=v*(p3[r]-p3[l-1]);
                return;
            }
            if(k->flag) pushdown(k);
            if(L<=k->mid) plus(k->ch[0],l,k->mid,L,R,v);
            if(R>k->mid) plus(k->ch[1],k->mid+1,r,L,R,v);
            pushup(k);
        }
        
};
class type *tree;
int main()
{
    for(LL i=1;i<=100000;i++)
    {
        p1[i]=p1[i-1]+1;
        p2[i]=p2[i-1]+i;
        p3[i]=p3[i-1]+i*i;
    }
    read(n);read(m);
    tree->build(root,1,n-1);
    char opt[5];
    for(LL x,y,z;m--;)
    {
        scanf("%s",opt+1);
        if(opt[1]=='C')
        {
            read(x);read(y);read(z);
            tree->plus(root,1,n-1,x,y-1,z);
        }
        else 
        {    
            read(x);read(y);
            ans1=ans2=ans3=0;
            tree->query(root,1,n-1,x,y-1);
            LL fm=((y-x+1)*(y-x))/2;
            LL fz=(y-x*y)*ans1+(x+y-1)*ans2-ans3;
            LL Gcd=gcd(fm,fz); 
            printf("%lld/",fz/Gcd);
            printf("%lld
",fm/Gcd);
        }
    }
    return 0;
}
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
原文地址:https://www.cnblogs.com/ruojisun/p/7308240.html