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

    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

    题解:

    要维护、求解在某个区间内随机选取区间的期望权值和,我们可以采用线段树。

    对于一个线段树节点,维护这几个参数:区间和sum、前缀和的前缀和qz、后缀和的后缀和hz、该区间的期望ans、区间长度len。

    合并区间时,

    ans[x]=ans[l]+ans[r]+hz[l]*len[r]+qz[r]*len[l];
    qz[x]=qz[l]+qz[r]+tot[l]*len[r]; hz[x]:=hz[l]+hz[r]+tot[r]*len[l];
    sum[x]=sum[l]+sum[r]; len[x]=len[l]+len[r];

    我们还要预处理出在长度为len的区间中随机选取区间时,期望选中几个点,用来实现区间增值的lazy标记。

    代码:

      1 type
      2   arr=array[0..3]of int64;
      3 var
      4   i,n,m,cnt:longint;
      5   j,k,l:int64;
      6   ans:array[0..200001]of arr;
      7   t:array[0..200001,-2..2]of longint;
      8   bs:array[0..200001]of int64;
      9   tot,ans1,ans2,ans3:int64;
     10   ch:char;
     11 procedure build(l,r,fa:longint);
     12 var x:longint;
     13 begin
     14   inc(cnt); x:=cnt; t[x,1]:=l; t[x,2]:=r;
     15   if t[fa,1]=t[x,1] then t[fa,-1]:=x else t[fa,-2]:=x;
     16   if l=r then exit;
     17   build(l,(l+r)div 2,x); build((l+r)div 2+1,r,x);
     18 end;
     19 procedure down(x:longint);
     20 var y:int64;
     21   l,r,ll,rr:int64;
     22 begin
     23   y:=t[x,0]; l:=t[x,-1]; r:=t[x,-2]; t[x,0]:=0;
     24   if y=0 then exit;
     25   if l>0 then
     26   begin
     27     t[l,0]:=t[l,0]+y; ans[l,3]:=ans[l,3]+(t[l,2]-t[l,1]+1)*y;
     28     ans[l,0]:=ans[l,0]+bs[(t[l,2]-t[l,1]+1)]*y;
     29     ll:=t[l,1]; rr:=t[l,2];
     30     ans[l,1]:=ans[l,1]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     31     ans[l,2]:=ans[l,2]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     32   end;
     33   if r>0 then
     34   begin
     35     t[r,0]:=t[r,0]+y; ans[r,3]:=ans[r,3]+(t[r,2]-t[r,1]+1)*y;
     36     ans[r,0]:=ans[r,0]+bs[(t[r,2]-t[r,1]+1)]*y;
     37     ll:=t[r,1]; rr:=t[r,2];
     38     ans[r,1]:=ans[r,1]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     39     ans[r,2]:=ans[r,2]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     40   end;
     41 end;
     42 function up(a,b:arr;x,y:longint):arr;
     43 begin
     44   up[0]:=a[0]+b[0]+a[2]*y+b[1]*x;
     45   up[1]:=a[1]+b[1]+a[3]*y; up[2]:=a[2]+b[2]+b[3]*x;
     46   up[3]:=a[3]+b[3];
     47 end;
     48 function qq(x,l,r:longint):arr;
     49 var ll,rr:int64;
     50 begin
     51   down(x);
     52   ll:=t[x,1]; rr:=t[x,2];
     53   if(ll=l)and(rr=r)then exit(ans[x]);
     54   if r<=(ll+rr)div 2 then exit(qq(t[x,-1],l,r));
     55   if l>(ll+rr)div 2 then exit(qq(t[x,-2],l,r));
     56   exit(up(qq(t[x,-1],l,(ll+rr)div 2),qq(t[x,-2],(ll+rr)div 2+1,r),
     57   (ll+rr)div 2-l+1,r-(ll+rr)div 2));
     58 end;
     59 procedure add(x,l,r:longint;y:int64);
     60 var ll,rr:int64;
     61 begin
     62   down(x);
     63   ll:=t[x,1]; rr:=t[x,2];
     64   if(ll=l)and(rr=r)then
     65   begin
     66     ans[x,0]:=ans[x,0]+bs[(rr-ll+1)]*y; ans[x,3]:=ans[x,3]+(rr-ll+1)*y;
     67     ans[x,1]:=ans[x,1]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     68     ans[x,2]:=ans[x,2]+((rr-ll+1+1)*(rr-ll+1)div 2)*y;
     69     t[x,0]:=y; exit;
     70   end;
     71   if r<=(ll+rr)div 2 then add(t[x,-1],l,r,y)else
     72   if l>(ll+rr)div 2 then add(t[x,-2],l,r,y)else
     73   begin
     74     add(t[x,-1],l,(ll+rr)div 2,y);
     75     add(t[x,-2],(ll+rr)div 2+1,r,y);
     76   end;
     77   ans[x]:=up(ans[t[x,-1]],ans[t[x,-2]],(ll+rr)div 2-ll+1,rr-(ll+rr)div 2);
     78 end;
     79 function gcd(x,y:int64):int64;
     80 begin
     81   if x=0 then exit(y);
     82   exit(gcd(y mod x,x));
     83 end;
     84 begin
     85   readln(n,m); dec(n);
     86   build(1,n,0);
     87   for i:=1 to n do
     88   begin
     89     tot:=tot+i;
     90     bs[i]:=bs[i-1]+tot;
     91   end;
     92   //for i:=1 to n do writeln(bs[i]);
     93   for i:=1 to m do
     94   begin
     95     read(ch);
     96     case ch of
     97       'C':begin readln(j,k,l); dec(k); add(1,j,k,l); end;
     98       'Q':begin
     99         readln(j,k); dec(k);
    100         ans1:=qq(1,j,k)[0]; ans2:=(k-j+2)*(k-j+1)div 2;
    101         ans3:=gcd(ans1,ans2);
    102         writeln(ans1 div ans3,'/',ans2 div ans3);
    103       end;
    104     end;
    105   end;
    106 end.
    View Code
  • 相关阅读:
    Windows Azure Web Site (19) Azure Web App链接到VSTS
    Windows Azure Virtual Machine (35) Azure VM通过Linked DB,执行SQL Job
    Azure PowerShell (16) 并行开关机Azure ARM VM
    Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering
    Azure ARM (21) Azure订阅的两种管理模式
    Windows Azure Platform Introduction (14) 申请海外的Windows Azure账户
    Azure ARM (20) 将非托管磁盘虚拟机(Unmanage Disk),迁移成托管磁盘虚拟机(Manage Disk)
    Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)
    Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)
    Azure Automation (6) 执行Azure SQL Job
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6525671.html
Copyright © 2011-2022 走看看