zoukankan      html  css  js  c++  java
  • BZOJ 2752: [HAOI2012]高速公路(road)

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

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1339  Solved: 497
    [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

     
    [Submit][Status][Discuss]

    好久不写题了,就是道线段树裸题。

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 typedef long long lnt;
      5 
      6 const int mxn = 200005;
      7 
      8 inline lnt pow(lnt a, int b) {
      9     lnt r = 1;
     10 
     11     for (; b; b >>= 1, a *= a)
     12         if (b & 1)r *= a;
     13 
     14     return r;
     15 }
     16 
     17 lnt gcd(lnt a, lnt b) {
     18     return b ? gcd(b, a % b) : a;
     19 }
     20 
     21 int n, m;
     22 
     23 struct node {
     24     lnt sum;
     25     lnt val;
     26     lnt tag;
     27     node *lsn;
     28     node *rsn;
     29 };
     30 
     31 inline node *newNode(void) {
     32     static node buf[mxn * 6];
     33     static node *tot = buf;
     34 
     35     return tot++;
     36 }
     37 
     38 struct segment {
     39     node *root;
     40 
     41     inline void build(int p) {
     42         root = build(1, n, p);
     43     }
     44 
     45     inline node *build(int l, int r, int p) {
     46         node *t = newNode();
     47 
     48         t->val = 0;
     49         t->tag = 0;
     50 
     51         if (l == r) {
     52             t->lsn = NULL;
     53             t->rsn = NULL;
     54             t->sum = pow(l, p);
     55         }
     56         else {
     57             int mid = (l + r) >> 1;
     58 
     59             t->lsn = build(l, mid, p);
     60             t->rsn = build(mid + 1, r, p);
     61 
     62             t->sum = t->lsn->sum + t->rsn->sum;
     63         }
     64 
     65         return t;
     66     }
     67 
     68     inline void add(int l, int r, lnt w) {
     69         add(root, 1, n, l, r, w);
     70     }
     71 
     72     void add(node *t, int l, int r, int x, int y, lnt w) {
     73         if (l == x && y == r) {
     74             t->tag += w;
     75             t->val += w * t->sum;
     76         }
     77         else {
     78             int mid = (l + r) >> 1;
     79 
     80             if (y <= mid)
     81                 add(t->lsn, l, mid, x, y, w);
     82             else if (x > mid)
     83                 add(t->rsn, mid + 1, r, x, y, w);
     84             else {
     85                 add(t->lsn, l, mid, x, mid, w);
     86                 add(t->rsn, mid + 1, r, mid + 1, y, w);
     87             }
     88 
     89             t->val = t->lsn->val + t->rsn->val;
     90 
     91             if (t->tag)
     92                 t->val += t->tag * t->sum;
     93         }
     94     }
     95 
     96     inline lnt qry(int l, int r) {
     97         return qry(root, 1, n, l, r);
     98     }
     99 
    100     lnt qry(node *t, int l, int r, int x, int y) {
    101         if (l == x && y == r)
    102             return t->val;
    103         else {
    104             int mid = (l + r) >> 1;
    105 
    106             if (t->tag) {
    107                 add(t->lsn, l, mid, l, mid, t->tag);
    108                 add(t->rsn, mid + 1, r, mid + 1, r, t->tag);
    109 
    110                 t->tag = 0;
    111             }
    112 
    113             if (y <= mid)
    114                 return qry(t->lsn, l, mid, x, y);
    115             else if (x > mid)
    116                 return qry(t->rsn, mid + 1, r, x, y);
    117             else
    118                 return qry(t->lsn, l, mid, x, mid) + qry(t->rsn, mid + 1, r, mid + 1, y);
    119         }
    120     }
    121 }tree[3];
    122 
    123 signed main(void) {
    124     scanf("%d%d", &n, &m), --n;
    125 
    126     for (int i = 0; i < 3; ++i)
    127         tree[i].build(i);
    128 
    129     for (char s[10]; m--; ) {
    130         if (scanf("%s", s), s[0] == 'C') {
    131             int l, r, v; scanf("%d%d%d", &l, &r, &v); --r;
    132 
    133             for (int i = 0; i < 3; ++i)
    134                 tree[i].add(l, r, v);
    135         }
    136         else {
    137             int l, r; scanf("%d%d", &l, &r); --r;
    138 
    139             lnt a = -tree[2].qry(l, r) + 1LL * (l + r) * tree[1].qry(l, r) - (1LL * l * r + l - r - 1) * tree[0].qry(l, r);
    140             lnt b = 1LL * (r - l + 2) * (r - l + 1) / 2;
    141             lnt t = gcd(a, b);
    142 
    143             a /= t;
    144             b /= t;
    145 
    146             printf("%lld/%lld
    ", a, b);
    147         }
    148     }
    149 }

    @Author: YouSiki

  • 相关阅读:
    CodeForces 660D Number of Parallelograms
    【POJ 1082】 Calendar Game
    【POJ 2352】 Stars
    【POJ 2481】 Cows
    【POJ 1733】 Parity Game
    【NOI 2002】 银河英雄传说
    【NOI 2015】 程序自动分析
    【POJ 1704】 Georgia and Bob
    【HDU 2176】 取(m堆)石子游戏
    【SDOI 2016】 排列计数
  • 原文地址:https://www.cnblogs.com/yousiki/p/6613263.html
Copyright © 2011-2022 走看看