【HAOI2012】高速公路

来源:互联网 发布:金融大数据 pdf 编辑:程序博客网 时间:2024/04/29 17:25
题目描述

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将期望花费多少费用呢?

输入输出格式

输入格式:

 

第一行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

 

输出格式:

 

对于每次询问操作回答一行,输出一个既约分数

若答案为整数a,输出a/1

 

输入输出样例

输入样例#1:
4 5C 1 4 2C 1 2 -1Q 1 2Q 2 4Q 1 4
输出样例#1:
1/18/317/6

说明

所有C操作中的v的绝对值不超过10000

在任何时刻任意道路的费用均为不超过10000的非负整数

所有测试点的详细情况如下表所示

Test N M

1    =10    =102    =100    =1003    =1000    =10004    =10000    =100005    =50000    =500006    =60000    =600007    =70000    =700008    =80000    =800009    =90000    =9000010    =100000    =100000

  1 /*  2     实际上n个点 只有n-1条路 那就删掉最后一个点   3     每次询问 r-1  4     期望定义自己百度去   5     这里期望可以用总和除以总状态数   6     总状态数显然可以用组合数 即 C(r-l+1,2);  7     总和指的是可能的收费总和  8     对于此题我们要对每个点分别计算贡献的话  9     每个点的贡献为左边点的数目加1的和乘右面点的数量乘这个点的权值 10     ∑(l-r) v[i]*(i-l+1)*(r-i+1); 11     化简一下 维护 v[i],v[i]*i,v[i]*i*i 即可  12 */ 13 #include<cstdio> 14 #include<iostream> 15 #define MAXN 100010 16 #define LL long long 17  18 using namespace std; 19  20 struct node { 21     LL l,r; 22     LL tag; 23     LL sum1,sum2,sum3; 24 }; 25 node t[MAXN<<3]; 26  27 LL n,m,x,y,v; 28  29 LL p[MAXN],p2[MAXN],p3[MAXN]; 30  31 char opt[5]; 32  33 inline void read(LL&x) {  34     LL f=1;x=0;char c=getchar();  35     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}  36     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}  37     x=x*f;  38 }  39  40 void build_tree(LL now,LL l,LL r) { 41     t[now].l=l; 42     t[now].r=r; 43     if(l==r) return; 44     LL mid=(l+r)>>1; 45     build_tree(now<<1,l,mid); 46     build_tree(now<<1|1,mid+1,r); 47 } 48  49 inline void up(LL now) { 50     t[now].sum1=t[now<<1].sum1+t[now<<1|1].sum1; 51     t[now].sum2=t[now<<1].sum2+t[now<<1|1].sum2; 52     t[now].sum3=t[now<<1].sum3+t[now<<1|1].sum3; 53 } 54  55 inline void down(LL now) { 56     if(t[now].tag) { 57         t[now<<1].sum1+=t[now].tag*(p[t[now<<1].r]-p[t[now<<1].l-1]); 58         t[now<<1].sum2+=t[now].tag*(p2[t[now<<1].r]-p2[t[now<<1].l-1]); 59         t[now<<1].sum3+=t[now].tag*(p3[t[now<<1].r]-p3[t[now<<1].l-1]); 60         t[now<<1].tag+=t[now].tag; 61         t[now<<1|1].sum1+=t[now].tag*(p[t[now<<1|1].r]-p[t[now<<1|1].l-1]); 62         t[now<<1|1].sum2+=t[now].tag*(p2[t[now<<1|1].r]-p2[t[now<<1|1].l-1]); 63         t[now<<1|1].sum3+=t[now].tag*(p3[t[now<<1|1].r]-p3[t[now<<1|1].l-1]); 64         t[now<<1|1].tag+=t[now].tag; 65         t[now].tag=0; 66     } 67     return; 68 } 69  70 void modify(LL now,LL l,LL r,LL k) { 71     if(l<=t[now].l&&r>=t[now].r) { 72         t[now].tag+=k; 73         t[now].sum1+=(p[t[now].r]-p[t[now].l-1])*k;  //这里应该是+= 而不是赋值  74         t[now].sum2+=(p2[t[now].r]-p2[t[now].l-1])*k; 75         t[now].sum3+=(p3[t[now].r]-p3[t[now].l-1])*k; 76         return; 77     } 78     down(now); 79     LL mid=(t[now].l+t[now].r)>>1; 80     if(l<=mid) modify(now<<1,l,r,k); 81     if(r>mid) modify(now<<1|1,l,r,k); 82     up(now); 83 } 84  85 inline void pre() { 86     for(LL i=1;i<=100000;i++) { 87         p[i]=p[i-1]+1; 88         p2[i]=p2[i-1]+i; 89         p3[i]=p3[i-1]+i*i; 90     } 91     return; 92 } 93  94 LL query1(LL now,LL l,LL r) { 95     if(l<=t[now].l&&r>=t[now].r) { 96         return t[now].sum1; 97     } 98     down(now); 99     LL res=0,mid=(t[now].l+t[now].r)>>1;100     if(l<=mid) res+=query1(now<<1,l,r);101     if(r>mid) res+=query1(now<<1|1,l,r);102     return res;103 }104 105 LL query2(LL now,LL l,LL r) {106     if(l<=t[now].l&&r>=t[now].r) {107         return t[now].sum2;108     }109     down(now);110     LL res=0,mid=(t[now].l+t[now].r)>>1;111     if(l<=mid) res+=query2(now<<1,l,r);112     if(r>mid) res+=query2(now<<1|1,l,r);113     return res;114 }115 116 LL query3(LL now,LL l,LL r) {117     if(l<=t[now].l&&r>=t[now].r) {118         return t[now].sum3;119     }120     down(now);121     LL res=0,mid=(t[now].l+t[now].r)>>1;122     if(l<=mid) res+=query3(now<<1,l,r);123     if(r>mid) res+=query3(now<<1|1,l,r);124     return res;125 }126 127 LL gcd(LL a,LL b) {128     if(b==0) return a;129     else gcd(b,a%b);130 }131 132 int main() {133     read(n);read(m);134     pre();135     build_tree(1,1,n-1);136     for(LL i=1;i<=m;i++) {137         scanf("%s",opt);138         if(opt[0]=='C') {139             read(x);read(y);read(v);140             modify(1,x,y-1,v);141         } 142         else {143             read(x);read(y);144             LL ans1=(y-x*y)*query1(1,x,y-1);145             LL ans2=(x+y-1)*query2(1,x,y-1);146             LL ans3=-query3(1,x,y-1);147             LL ans=ans1+ans2+ans3;148             LL fm=((y-x+1)*(y-x))>>1;149             LL p=gcd(ans,fm);150             printf("%lld/%lld\n",ans/p,fm/p);151         }152     }153     return 0;154 }
题解

 

原创粉丝点击