列表

详情


NC19991. [HAOI2012]高速公路(ROAD)

描述

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

输入描述

第一行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

输出描述

对于每次询问操作回答一行,输出一个既约分数

若答案为整数a,输出a/1

示例1

输入:

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

输出:

1/1
8/3
17/6

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 210ms, 内存消耗: 14052K, 提交时间: 2019-03-09 15:37:46

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
#define R register
#define IN inline
#define gc getchar()
#define W while
#define MX 100050
#define ll long long
bool neg;
template <class T>
IN void in(T &x)
{
    x = 0; R char c = gc;
    for (; !isdigit(c); c = gc)
    if(c == '-') neg = true;
    for (;  isdigit(c); c = gc)
    x = (x << 1) + (x << 3) + c - 48;
    if(neg) neg = false, x = -x;
}
struct Node {ll lsum, rsum, sum, len, ans, tag;} tree[MX << 2];
int dot, q;
namespace SGT
{
    #define ls (now << 1)
    #define rs (now << 1 | 1)
    IN ll F1(ll x) {return x * (x + 1) * (x + 1) / 2;}
    IN ll F2(ll x) {return x * (x + 1) * (x * 2 + 1) / 6;}
    IN void pushdown(R int now)
    {
        if(tree[now].tag)
        {
            ll buf;
            tree[ls].tag += tree[now].tag; tree[rs].tag += tree[now].tag;
            buf = tree[ls].len * (tree[ls].len + 1) / 2 * tree[now].tag;
            tree[ls].lsum += buf, tree[ls].rsum += buf;
            buf = tree[rs].len * (tree[rs].len + 1) / 2 * tree[now].tag;
            tree[rs].lsum += buf, tree[rs].rsum += buf;
            tree[ls].sum += tree[now].tag * tree[ls].len;
            tree[rs].sum += tree[now].tag * tree[rs].len;
            tree[ls].ans += (F1(tree[ls].len) - F2(tree[ls].len)) * tree[now].tag;
            tree[rs].ans += (F1(tree[rs].len) - F2(tree[rs].len)) * tree[now].tag;
            tree[now].tag = 0;
        }
    }
    IN void pushup(R int now)
    {
        tree[now].sum = tree[ls].sum + tree[rs].sum;
        tree[now].lsum = tree[ls].lsum + tree[rs].lsum + tree[ls].sum * tree[rs].len;
        tree[now].rsum = tree[ls].rsum + tree[rs].rsum + tree[rs].sum * tree[ls].len;
        tree[now].ans = tree[ls].ans + tree[rs].ans + tree[ls].len * tree[rs].lsum + tree[rs].len * tree[ls].rsum;
    }
    IN Node merge (const Node &x, const Node &y)
    {
        Node ret;
        ret.len = x.len + y.len;
        ret.sum = x.sum + y.sum;
        ret.lsum = x.lsum + y.lsum + x.sum * y.len;
        ret.rsum = x.rsum + y.rsum + y.sum * x.len;
        ret.ans = x.ans + y.ans + x.len * y.lsum + y.len * x.rsum;
        return ret;
    }
    void build(R int now, R int lef, R int rig)
    {
        if(lef == rig) return tree[now].len = 1, void();
        int mid = lef + rig >> 1;
        build(ls, lef, mid), build(rs, mid + 1, rig);
        tree[now].len = tree[ls].len + tree[rs].len;
    }
    void modify(R int now, R int lef, R int rig, R int lb, R int rb, R int del)
    {
        if(lef >= lb && rig <= rb)
        {
            ll buf;
            tree[now].tag += del;
            tree[now].sum += tree[now].len * del;
            buf = tree[now].len * (tree[now].len + 1) * del / 2;
            tree[now].lsum += buf, tree[now].rsum += buf;
            tree[now].ans += (F1(tree[now].len) - F2(tree[now].len)) * del;
            return;
        }
        pushdown(now);
        int mid = lef + rig >> 1;
        if(lb <= mid) modify(ls, lef, mid, lb, rb, del);
        if(rb >  mid) modify(rs, mid + 1, rig, lb, rb, del);
        pushup(now);
    }
    Node query(R int now, R int lef, R int rig, R int lb, R int rb)
    {
        if(lef >= lb && rig <= rb) return tree[now];
        int mid = lef + rig >> 1;
        pushdown(now);
        if(rb <= mid) return query(ls, lef, mid, lb, rb);
        else if(lb > mid) return query(rs, mid + 1, rig, lb, rb);
        else return merge(query(ls, lef, mid, lb, rb), query(rs, mid + 1, rig, lb, rb));
    }
    #undef ls
    #undef rs
}
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
int main(void)
{
    char buf[3]; int a, b, c; ll as, g, tar;
    in(dot), in(q); Node res;
    SGT::build(1, 1, dot - 1);
    W (q--)
    {
        scanf("%s", buf);
        if(buf[0] == 'C')
        {
            in(a), in(b), in(c);
            SGT::modify(1, 1, dot - 1, a, b - 1, c);
        }
        else 
        {
            in(a), in(b);
            res = SGT::query(1, 1, dot - 1, a, b - 1);
            as = res.ans, tar = 1ll * (b - a) * (b - a + 1) / 2;
            g = gcd(tar, as), printf("%lld/%lld\n", as / g, tar / g);
        }
    }
}

上一题