题目描述
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 5 C 1 4 2 C 1 2 -1 Q 1 2 Q 2 4 Q 1 4
输出样例#1:
复制
1/1 8/3 17/6
题意:两点之间区间和的期望值
非常好的线段树题
注意 (r-i+1)*(i-l+1) 这个公式之前cf有题用到过
学会了维护
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define pb push_back #define inf 0x3f3f3f3f #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 typedef pair<int,int>pii; ////////////////////////////////// const int N=1e6+5; ll t1[N<<2],t2[N<<2],t3[N<<2],sum2[N<<2],sum3[N<<2],col[N<<2]; ll ans1,ans2,ans3; void up(ll pos) { t1[pos]=t1[pos<<1]+t1[pos<<1|1];t2[pos]=t2[pos<<1]+t2[pos<<1|1];t3[pos]=t3[pos<<1]+t3[pos<<1|1]; } void down(ll m,ll pos) { if(col[pos]) { col[pos<<1]+=col[pos];col[pos<<1|1]+=col[pos]; t1[pos<<1]+=(m-(m>>1))*col[pos];t1[pos<<1|1]+=(m>>1)*col[pos]; t2[pos<<1]+=col[pos]*sum2[pos<<1];t2[pos<<1|1]+=col[pos]*sum2[pos<<1|1]; t3[pos<<1]+=col[pos]*sum3[pos<<1];t3[pos<<1|1]+=col[pos]*sum3[pos<<1|1]; col[pos]=0; } } void build(ll l,ll r,ll pos) { if(l==r){sum2[pos]=l;sum3[pos]=l*l;return;} int m=(l+r)>>1;build(lson);build(rson); sum2[pos]=sum2[pos<<1]+sum2[pos<<1|1]; sum3[pos]=sum3[pos<<1]+sum3[pos<<1|1]; } void upsum(ll L,ll R,ll v,ll l,ll r,ll pos) { if(L<=l&&r<=R){ t1[pos]+=(r-l+1)*v; t2[pos]+=sum2[pos]*v;t3[pos]+=sum3[pos]*v;col[pos]+=v;return ; } int m=(l+r)>>1;down(r-l+1,pos); if(L<=m)upsum(L,R,v,lson);if(R>m)upsum(L,R,v,rson); up(pos); } void qsum(ll L,ll R,ll l,ll r,ll pos) { if(L<=l&&r<=R){ ans1+=t1[pos];ans2+=t2[pos];ans3+=t3[pos];return ; } int m=(l+r)>>1;down(r-l+1,pos); if(L<=m)qsum(L,R,lson);if(R>m)qsum(L,R,rson);up(pos); } ll n,m,a,b,c; ll l,r; char s[3]; int main() { cin>>n>>m;n--; build(1,n,1); while(m--) { RS(s);cin>>l>>r;r--; if(s[0]=='C'){ ll c;cin>>c;;upsum(l,r,c,1,n,1); } else { ans1=ans2=ans3=0; qsum(l,r,1,n,1); ll x=ans1*(r-l+1-l*r)+(l+r)*ans2-ans3; ll y=(1+r-l+1)*(r-l+1)/2; ll temp=__gcd(x,y); printf("%lld/%lld\n",x/temp,y/temp); } } return 0; }