• BZOJ 2572 高速公路


    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

    开始时,并不知道怎么用线段树维护期望,向lyp咨询了下,然后他教会了我怎么做:
    对于一段区间l,r,ans=∑ki*pi。ki指的是这个点的权值,pi指对答案贡献的概率。
    现在我们想pi怎么计算。pi=(i-l+1)(r-i+1)/((r-l+1)(r-l+2)/2)。对于某个i,要选到他,必须从其前面的(i-l+1)中选一个(包括自身)和后面的(r-i+1)中选一个(也包括自身),而总共的方案为C(n+1,2)=((r-l+1)(r-l+2)/2)。
    所以,ans=∑ki(i-l+1)(r-i+1)/((r-l+1)(r-l+2)/2),分母是一定的,所以可以提出,所以我们要求的即为ans=∑ki*(i-l+1)*(r-i+1)。
    令L=l-1,R=r+1。ans=∑ki(i-L)(R-i)=∑ki(-i2+(R+L)i-RL)=∑-i2ki+(R+L)∑iki-RL∑ki。就连蒟蒻的我都看出怎么维护了。。。三个sum数组:ki,iki,i2ki
    PS:注意看题。我们按照由西向东的顺序将收费站依次编号为1~N,从收费站i行驶到i+1(或从i+1行驶到i)需要收取Vi的费用。所有输入的r都要减一。
     
      1 #include<cstdio>
      2 #include<cstdlib>
      3 using namespace std;
      4 
      5 typedef long long ll;
      6 #define maxn 100010
      7 
      8 ll n,m;
      9 struct node
     10 {
     11     ll sign; ll s1,s2,s3;
     12     inline node() { sign = s1 = s2 = s3 = 0; }
     13     friend inline node operator +(const node &x,const node &y)
     14     {
     15         node ret;
     16         ret.s1 = x.s1+y.s1;
     17         ret.s2 = x.s2+y.s2;
     18         ret.s3 = x.s3+y.s3;
     19         return ret;
     20     }
     21 }tree[maxn*4];
     22 
     23 inline ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; }
     24 
     25 inline void modify(ll l,ll r,ll now,ll key)
     26 {
     27     tree[now].sign += key;
     28     tree[now].s1 += (r - l + 1)*key;
     29     tree[now].s2 += ((ll)r*(ll)(r+1)*(ll)(2*r+1)/(ll)6-(ll)(l-1)*(ll)l*(ll)(2*l-1)/(ll)6)*key;
     30     tree[now].s3 += (ll)(l+r)*(ll)(r-l+1)/(ll)2*key;
     31 }
     32 
     33 inline void pushdown(ll l,ll r,ll now)
     34 {
     35     if (!tree[now].sign) return;
     36     if (l != r)
     37     {
     38         ll mid = (l + r) >> 1;
     39         modify(l,mid,now<<1,tree[now].sign);
     40         modify(mid+1,r,(now<<1)+1,tree[now].sign);
     41     }
     42     tree[now].sign = 0;
     43     return;
     44 }
     45 
     46 inline void updata(ll now)
     47 {
     48     ll t = tree[now].sign;
     49     tree[now] = tree[now<<1]+tree[(now<<1)+1];
     50     tree[now].sign = t;
     51 }
     52 
     53 inline void change(ll l,ll r,ll now,ll ql,ll qr,ll key)
     54 {
     55     pushdown(l,r,now);
     56     if (l >= ql&&r <= qr)
     57     {
     58         modify(l,r,now,key);
     59         return;
     60     }
     61     ll mid = (l + r) >> 1;
     62     if (qr <= mid) change(l,mid,now<<1,ql,qr,key);
     63     else if (ql > mid) change(mid+1,r,(now<<1)+1,ql,qr,key);
     64     else change(l,mid,now<<1,ql,mid,key),change(mid+1,r,(now<<1)+1,mid+1,qr,key);
     65     updata(now);
     66 }
     67 
     68 inline node ask(ll l,ll r,ll now,ll ql,ll qr)
     69 {
     70     pushdown(l,r,now);
     71     if (l >= ql&&r <= qr) return tree[now];
     72     ll mid = (l + r) >> 1;
     73     if (qr <= mid) return ask(l,mid,now<<1,ql,qr);
     74     else if (ql > mid) return ask(mid+1,r,(now<<1)+1,ql,qr);
     75     else return ask(l,mid,now<<1,ql,mid)+ask(mid+1,r,(now<<1)+1,mid+1,qr);
     76 }
     77 
     78 int main()
     79 {
     80     freopen("2752.in","r",stdin);
     81     freopen("2752.out","w",stdout);
     82     scanf("%lld %lld
    ",&n,&m);
     83     while (m--)
     84     {
     85         char opt; scanf("%c",&opt);
     86         if (opt == 'C')
     87         {
     88             ll l,r,v; scanf("%lld %lld %lld
    ",&l,&r,&v);
     89             --r;
     90             change(1,n,1,l,r,v);
     91         }
     92         else
     93         {
     94             ll l,r; scanf("%lld %lld
    ",&l,&r); r--;
     95             node ret = ask(1,n,1,l,r);
     96             ll L = l-1,R = r+1;
     97             ll up = -(L*R)*ret.s1-ret.s2+(L+R)*ret.s3,down = (ll)(r-l+1)*(ll)(r-l+2)>>1LL,d = gcd(up,down);
     98             up /= d; down /= d;
     99             printf("%lld/%lld
    ",up,down);
    100         }
    101     }
    102     fclose(stdin); fclose(stdout);
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    Nexus OSS 3 搭建 Docker & Git LFS 仓库
    YARN FairScheduler
    k8s基本概念及使用
    k8s 基本使用
    10款非常实用的在线网站原型设计工具
    Spark常见问题及性能调优
    spark常见问题处理
    TensorFlow 基本使用
    c语言数组的操作
    在Android开发中遇到的MediaPlayer问题
  • 原文地址:https://www.cnblogs.com/mmlz/p/4274736.html
Copyright © 2020-2023  润新知