bzoj 2752 9.20考试第三题 高速公路(road)题解

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

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

  考试前一天晚上做梦,梦见自己考试140,倒数第二,一开始以为自己只是日有所思夜有所梦,然后……这道题助我梦想成真/(ㄒoㄒ)/~~然而最终只有20分……

  其实当天已经推出来了式子,然而由于不敢去打,只能打了区间修改单点查询的打法,结果还全E了,好尴尬啊,连暴力的40分都没拿到。

  基本大多数人都可以推到这里——一个边对于答案的贡献(不算分母):设这条边为第i条边,询问为l,r:(i-l+1)*(r-i)*v[i]。

  然后我们大可把这个式子展开为:

      r*(i+1)*v[i]+i*l*v[i]-l*r*v[i]-i*(i+1)*v[i]。

  由于l,r随询问而变,我们无从得知,但由于求得是上述式子的最终值,我们可以去维护上式中的四个单项式,以及他们的系数。

  通过系数我们就可以很轻松的应对区间修改,因为系数是不受任何影响的,而对于每一个修改,对于答案的影响就是修改值乘以系数,这样我们的修改查询都是log n的了。

  最后叮嘱的一点是long long 不然会死的很惨。

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<vector>
 10 #define N 100004
 11 #define int long long
 12 using namespace std;
 13 int n,m;
 14 struct no
 15 {
 16     int left,right,mid;
 17     long long lazy;
 18     long long data[5];
 19     long long sum[5];
 20 }node[N*4];
 21 long long gcd(long long a,long long b)
 22 {
 23     if(b==0)return a;
 24     return gcd(b,a%b);
 25 }
 26 void pushup(int x)
 27 {
 28     for(int i=1;i<=4;i++)
 29     {
 30         node[x].data[i]=node[x*2].data[i]+node[2*x+1].data[i];
 31         node[x].sum[i]=node[x*2].sum[i]+node[2*x+1].sum[i];
 32     }
 33 }
 34 void build(int left,int right,int x)
 35 {
 36     node[x].left=left,node[x].right=right;
 37     if(left==right)
 38     {
 39         node[x].data[1]=left+1;
 40         node[x].data[2]=left;
 41         node[x].data[3]=1;
 42         node[x].data[4]=left*(left+1);
 43         return;
 44     }
 45     int mid=(left+right)>>1;
 46     node[x].mid=mid;
 47     build(left,mid,2*x);
 48     build(mid+1,right,2*x+1);
 49     pushup(x);
 50 }
 51 struct inf
 52 {
 53     long long a,b;
 54 };
 55 char b[50];
 56 void pushdown(int x)
 57 {
 58     if(node[x].lazy)
 59     {
 60         node[2*x].lazy+=node[x].lazy;
 61         node[x*2+1].lazy+=node[x].lazy;
 62         for(int i=1;i<=4;i++)
 63         {
 64             node[2*x].sum[i]+=node[x].lazy*node[2*x].data[i];
 65             node[2*x+1].sum[i]+=node[x].lazy*node[2*x+1].data[i];
 66         }
 67         node[x].lazy=0;
 68     }
 69 }
 70 void add(int left,int right,int x,int z)
 71 {
 72     if(node[x].left==left&&node[x].right==right)
 73     {
 74         node[x].lazy+=z;
 75         for(int i=1;i<=4;i++)
 76             node[x].sum[i]+=node[x].data[i]*z;
 77         return;
 78     }
 79     pushdown(x);
 80     int mid=node[x].mid;
 81     if(left>mid)
 82         add(left,right,x*2+1,z);
 83     else if(right<=mid)
 84         add(left,right,2*x,z);
 85     else
 86         add(left,mid,x*2,z),add(mid+1,right,2*x+1,z);
 87     pushup(x);
 88 }
 89 inf get(long long left,long long right,int x,long long l,long long r)
 90 {
 91     if(node[x].left==left&&node[x].right==right)
 92     {
 93         inf aa;
 94         aa.a=node[x].sum[1]*r-l*r*node[x].sum[3];
 95         aa.a-=node[x].sum[4];
 96         aa.a+=l*node[x].sum[2];
 97         aa.b=(r-l+1)*(r-l)/2;
 98         long long t=gcd(aa.a,aa.b);
 99         aa.a/=t;
100         aa.b/=t;
101         return aa;
102     }
103     pushdown(x);
104     int mid=node[x].mid;
105     if(left>mid)
106         return get(left,right,2*x+1,l,r);
107     else if(right<=mid)
108         return get(left,right,2*x,l,r);
109     else
110     {
111         inf aa=get(left,mid,2*x,l,r);
112         inf bb=get(mid+1,right,2*x+1,l,r);
113         if(aa.b==bb.b)
114         {
115             aa.a+=bb.a;
116             long long t=gcd(aa.a,aa.b);
117             if(t!=1)
118                 aa.a/=t,aa.b/=t;
119             return aa;
120         }
121         else
122         {
123             long long tt=gcd(aa.b,bb.b);
124             long long c;
125             if(aa.b%tt==0)
126             {
127                 c=aa.b/tt;
128                 c*=bb.b;
129             }
130             else if(bb.b%tt==0)
131             {
132                 c=bb.b/tt;
133                 c*aa.b;
134             }
135             else
136             {
137                 c=aa.b*bb.b/tt;
138             }
139             aa.a*=c/aa.b;
140             bb.a*=c/bb.b;
141             aa.a+=bb.a;
142             aa.b=c;
143             long long t=gcd(aa.a,aa.b);
144             if(t!=1)
145                 aa.a/=t,aa.b/=t;
146             return aa;
147         }
148     }
149 }
150 signed main()
151 {
152     scanf("%lld%lld",&n,&m);
153     build(1,n-1,1);
154 while(m--)
155 {
156     scanf("%s",b);
157     if(b[0]==‘C‘)
158     {
159         int l,r,z;
160         scanf("%lld%lld%lld",&l,&r,&z);
161         add(l,r-1,1,z);
162     }
163     else
164     {
165         long long l,r;
166         scanf("%lld%lld",&l,&r);
167         inf tt=get(l,r-1,1,l,r);
168         printf("%lld/%lld\n",tt.a,tt.b);
169     }
170 }
171     return 0;
172 }

时间: 2024-10-06 10:08:53

bzoj 2752 9.20考试第三题 高速公路(road)题解的相关文章

9.27考试 SD_le NOIP模拟题 第三题 建造游乐场题解

这道题当时没读完题时脑部了无数种问法,然而最后还是猝不及防.一开始还以为是结论题,然而死也退不出来,就先去打第二题了.然后在想这道题时,我想到的是这样的思路(由于当时时间紧迫,尚未完善): 我每次向图中增加两个点,那么这两个点对于所有入度为偶数的点是否连接一定是一致的,如果这两个点相连,那么如果使他们分别和一个入度为单数的点相连,那么他们就是新的入度为单数的点,其他情况就不叙述了,太多了.还不是正解. 由于最后时间太紧迫了,我不得不打暴力去保分,结果还好丢人好丢人的打错了-- 正解其实还是挺有意

9-25考试第三题解题报告(还是写了指针翻译神马的都是浮云感觉好久不说话连话都不会说了233333333QVO)

type link=^pnode; pnode=record w:longint; next:link; end; var a,root:array[0..1122] of longint; g:array[0..1100,0..1100] of longint; hash:array[0..1122] of boolean; list:array[0..1122] of link; n,min:longint; procedure init; begin assign(input,'badne

2019年12月CSP考试第三题化学方程式解法

import sys import re def merge(m1, m2): for key in m1.keys(): if key in m2.keys(): m2[key] += m1[key] else: m2[key] = m1[key] return m2 def mul_formula(coef, formula): for key in formula.keys(): formula[key] *= coef return formula def equation(s): ex

【OC复合题】之定义一个学生类,需要有姓名,年龄,考试成绩三个成员属性,创建5个对象,属性可以任意值。(Objective-C)

题目: 定义一个学生类,需要有姓名,年龄,考试成绩三个成员属性,创建5个对象,属性可以任意值.(Objective-C) 1)    不使用@property,手动编写他们的访问器方法(getter和setter),注意内存管理(手动管理内存) 2)    增加一个便利构造器(快速构造器) 3)    使用NSLog输出学生对象时,输出信息格式为:My Name Is XXX  Age Is XXX Score Is XXX 4)    对5个学生对象按照成绩->年龄->姓名优先级排序(成绩相

2016年上半年信息系统管理工程师考试上午真题(1)

通过信息系统管理工程师考试并获得证书的人员,能聘任对应技术岗位,能评中级职称.下面希赛软考学院为您整理了2016年上半年信息系统管理工程师上午真题,助准备参加考试的你一臂之力. 2016年上半年信息系统管理工程师考试上午真题(1-25题) ●CPU主要包含(1)等部件. A.运算器.控制器和系统总线 B.运算器.寄存器组和内存储器 C.运算器.控制器和寄存器组 D.控制器.指令译码器和寄存器组 ●按照(2),可将计算机分为RISC(精简指令集计算机)和CISC(复杂指令集计算机). A.规模和处

树套树三题 题解

1.COGS 1534 [NEERC 2004]K小数 其实是主席树裸题…… (其实这题数据非常水……从O(nlogn)的主席树到O(nlog3n)的树套树+二分到O(nsqrt(n)log2n)的分块套二分套二分到O(n2)的暴力都能过……) 鉴于这就是动态排名系统的静态版,就不说了,贴代码: 线段树套平衡树: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; con

2016/1/12 第一题 输出 i 出现次数 第二题 用for循环和if条件句去除字符串中空格 第三题不用endwith 实现尾端字符查询

1 import java.util.Scanner; 2 3 4 public class Number { 5 6 private static Object i; 7 8 /* 9 *第一题 mingrikejijavabu中字符“i” 出现了几次,并将结果输出*/ 10 public static void main(String[] args) { 11 12 String r ="imingrikejijavabi"; 13 14 15 //第一种 截取 16 int a=

复旦大学2016--2017学年第二学期(16级)高等代数II期末考试第七大题解答

七.(本题10分)  设 $n$ 阶复方阵 $A$ 的特征多项式为 $f(\lambda)$, 复系数多项式 $g(\lambda)$ 满足 $(f(\lambda),g'(\lambda))=1$. 证明: $A$ 可对角化的充要条件是 $g(A)$ 可对角化. 证明  先证必要性. 设 $A$ 可对角化, 即存在非异阵 $P$, 使得 $P^{-1}AP=\Lambda=\mathrm{diag}\{\lambda_1,\lambda_2,\cdots,\lambda_n\}$ 为对角阵,

2016上半年网络工程师考试上午真题(51-75)

2016年上半年网络工程师考试真题是备战下半年网络工程师考试的最佳资料,下面希赛软考学院为您整理了上午试题,供您参考学习. 2016年上半年网络工程师考试上午真题(51-75) ●下面4个主机地址中属于网络220.115.200.0/21的地址是(51). A.220.115.198.0 B.220.115.206.0 C.220.115.217.0 D.220.115.224.0 ●假设路由表有4个表项如下所示,那么与地址115.120.145.67匹配的表项是(52),与地址115.120.