• 【BZOJ2752】【线段树】高速公路


    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

    【分析】

    比较简单的题目,推一下就知道要维护的值。

    但是细节比较多,并且要维护好几个值,容易写错,建议在草稿纸上对着公式打。

    明明超内存被bzoj说成TLE,你让我情何以堪...

      1 /*
      2 宋代志南
      3 《绝句》
      4 古木阴中系短篷,杖藜扶我过桥东。
      5 沾衣欲湿杏花雨,吹面不寒杨柳风。
      6 */
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <algorithm>
     10 #include <cstring>
     11 #include <vector>
     12 #include <utility>
     13 #include <iomanip>
     14 #include <string>
     15 #include <cmath>
     16 #include <queue>
     17 #include <assert.h>
     18 #include <map>
     19 #include <ctime>
     20 #include <cstdlib>
     21 #include <stack>
     22 #define LOCAL
     23 const int MAXN = 500000 + 10;
     24 const int MAXM = 1000000 + 10;
     25 const int INF = 100000000;
     26 const int SIZE = 450;
     27 const int maxnode =  1000000 + 10;
     28 using namespace std;
     29 long long add(long long val, long long len){
     30     return val * (((len * (len + 1)) / 2) * len + (len * (len + 1)) / 2 - (len * (len + 1) * (2 * len + 1)) / 6); 
     31 }
     32 long long n, m;
     33 struct SEGTREE{
     34        struct Node{
     35               long long l, r;
     36               long long sum, sum2, sum3;//代表总段和和带权和后面是反向的 
     37               long long addn, val;//val值代表整个区间的值 
     38               Node *ch[2];
     39               bool delta;//标记 
     40               
     41               void pushdown(){//标记下传 
     42                    if (l == r) return;
     43                    if (delta){
     44                       ch[0]->addn += addn;
     45                       ch[1]->addn += addn;
     46                       ch[0]->delta = 1;ch[0]->sum += add(addn, ch[0]->r - ch[0]->l + 1);ch[0]->val += addn * (ch[0]->r - ch[0]->l + 1);
     47                       ch[1]->delta = 1;ch[1]->sum += add(addn, ch[1]->r - ch[1]->l + 1);ch[1]->val += addn * (ch[1]->r - ch[1]->l + 1);
     48                       long long len = ch[0]->r - ch[0]->l + 1; 
     49                       ch[0]->sum2 += addn * ((len * (len + 1)) / 2);
     50                       ch[0]->sum3 += addn * ((len * (len + 1)) / 2);
     51                       len = ch[1]->r - ch[1]->l + 1;
     52                       ch[1]->sum2 += addn * ((len * (len + 1)) / 2); 
     53                       ch[1]->sum3 += addn * ((len * (len + 1)) / 2); 
     54                       delta = 0;
     55                       addn = 0;
     56                    }
     57                    return;
     58               }
     59               void update(){
     60                    if (l == r) return;
     61                    val = ch[0]->val + ch[1]->val;
     62                    //正反向 
     63                    sum2 = ch[0]->sum2 + ch[1]->sum2 + ch[1]->val * (ch[0]->r - ch[0]->l + 1);
     64                    sum3 = ch[1]->sum3 + ch[0]->sum3 + ch[0]->val * (ch[1]->r - ch[1]->l + 1);
     65                    sum = 0;
     66                    sum += ch[0]->sum + ch[0]->sum2 * (ch[1]->r - ch[1]->l + 1);
     67                    sum += ch[1]->sum + ch[1]->sum3 * (ch[0]->r - ch[0]->l + 1);
     68                    return;
     69               }
     70        }*root, mem[maxnode]; 
     71        long long tot;
     72        
     73        void init(){
     74             root = NULL;
     75             tot = 0;
     76             build(root, 1, n - 1);//n个点n-1条边 
     77        }
     78        Node *NEW(long long l, long long r){
     79             Node *p = &mem[tot++];
     80             p->l = l;
     81             p->r = r;
     82             p->addn = p->delta = p->val = p->sum2 = 0;
     83             return p;
     84        }
     85        void build(Node *&t, long long l, long long r){
     86             if (t == NULL){
     87                t = NEW(l, r);
     88             }
     89             if (l == r)  return;
     90             long long mid = (l + r) >> 1;
     91             build(t->ch[0], l, mid);
     92             build(t->ch[1], mid + 1, r);
     93             return; 
     94        }
     95        //lr一段的值全部加val 
     96        void insert(Node *&t, long long l, long long r, long long val){
     97             t->pushdown();
     98             if (l <= t->l && t->r <= r){
     99                t->delta = 1;
    100                t->addn += val;
    101                t->sum += add(val, t->r - t->l + 1);
    102                t->val += val * (t->r - t->l + 1);
    103                long long len = t->r - t->l + 1;
    104                t->sum2 += val * ((len * (len + 1)) / 2);
    105                t->sum3 += val * ((len * (len + 1)) / 2); 
    106                return;
    107             }
    108             long long mid = (t->l + t->r) >> 1;
    109             if (l <= mid) insert(t->ch[0], l, r, val);
    110             if (r > mid) insert(t->ch[1], l, r, val);
    111             t->update();
    112        }
    113        long long query(Node *&t, long long l, long long r){
    114            t->pushdown();
    115            if (l <= t->l && t->r <= r){
    116               long long Ans = t->sum;
    117               //先朝右边扩张
    118               Ans += (t->sum2 * (r - t->r));
    119               Ans += ((t->sum3 + t->val * (r - t->r)) * (t->l - l));
    120               return Ans;
    121            }
    122            long long mid = (t->l + t->r) >> 1;
    123            long long tmp = 0;
    124            if (l <= mid) tmp += query(t->ch[0], l, r);
    125            if (r > mid) tmp += query(t->ch[1], l, r);
    126            t->update();
    127            return tmp;
    128        }
    129 }A;
    130 
    131 void init(){
    132      scanf("%lld%lld", &n, &m);
    133      A.init();
    134 }
    135 long long gcd(long long a, long long b){return b == 0 ? a: gcd(b, a % b);}
    136 void work(){
    137      for (long long i = 1; i <= m; i++){
    138          char str[5];
    139          scanf("%s", str);
    140          if (str[0] == 'C'){
    141             long long l, r;
    142             long long val;
    143             scanf("%lld%lld%lld", &l, &r, &val);
    144             r--;
    145             A.insert(A.root, l, r, val); 
    146          }else if (str[0] == 'Q'){
    147             long long l, r;
    148             scanf("%lld%lld", &l, &r);
    149             long long tmp = r - l + 1;
    150             r--;
    151             if (l == 1 && r == 3)
    152             printf("");
    153             long long a = A.query(A.root, l, r), b = (tmp * (tmp - 1)) / 2;
    154             long long c = gcd(a, b);
    155             printf("%lld/%lld
    ", a / c, b / c);
    156          }
    157      }
    158 }
    159 
    160 int main(){
    161     
    162     init();
    163     work();
    164     return 0;
    165 }
    View Code
  • 相关阅读:
    MySQL之ORM
    MySQL之索引补充
    MySQL存储过程
    c primer plus 7编程练习
    c语言中统计单词数目程序
    c语言统计输入字符数及行数
    c语言中getchar()、putchar()函数例子
    c primer plus 6编程练习
    c语言 %c 一次输出多个字符 (特殊程序)
    c语言 复合赋值运算符的优先级低于算术运算符
  • 原文地址:https://www.cnblogs.com/hoskey/p/4337705.html
Copyright © 2020-2023  润新知