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
数据规模
所有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
#include <ctype.h>
#include <cstdio>
#define N 200020
typedef long long LL;
void read(LL &x)
{
x=0;
bool f=0;
register char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch==‘-‘) f=1;
for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-‘0‘;
x=f?(~x)+1:x;
}
LL ans1,ans2,ans3,p1[N],p2[N],p3[N],n,m;
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
struct typetree
{
LL l,r,mid;
LL sum1,sum2,sum3,flag;
typetree *ch[2];
typetree ()
{
ch[0]=ch[1]=NULL;
sum1=sum2=sum3=flag=0;
}
}*root=new typetree;
class type
{
private:
inline void pushup(typetree *&k)
{
k->sum1=k->ch[0]->sum1+k->ch[1]->sum1;
k->sum2=k->ch[0]->sum2+k->ch[1]->sum2;
k->sum3=k->ch[0]->sum3+k->ch[1]->sum3;
}
inline void pushdown(typetree *&k)
{
if(k->l==k->r) return;
k->ch[0]->flag+=k->flag;
k->ch[1]->flag+=k->flag;
k->ch[0]->sum1+=k->flag*(p1[k->ch[0]->r]-p1[k->ch[0]->l-1]);
k->ch[0]->sum2+=k->flag*(p2[k->ch[0]->r]-p2[k->ch[0]->l-1]);
k->ch[0]->sum3+=k->flag*(p3[k->ch[0]->r]-p3[k->ch[0]->l-1]);
k->ch[1]->sum1+=k->flag*(p1[k->ch[1]->r]-p1[k->ch[1]->l-1]);
k->ch[1]->sum2+=k->flag*(p2[k->ch[1]->r]-p2[k->ch[1]->l-1]);
k->ch[1]->sum3+=k->flag*(p3[k->ch[1]->r]-p3[k->ch[1]->l-1]);
k->flag=0;
}
public:
void haha(){build(root,1,n-1);}
void build(typetree *&k,LL l,LL r)
{
k=new typetree;
k->l=l;k->r=r;
if(l==r) return;
k->mid=(l+r)>>1;
build(k->ch[0],l,k->mid);
build(k->ch[1],k->mid+1,r);
}
void query(typetree *&k,LL l,LL r,LL L,LL R)
{
if(L<=l&&r<=R)
{
ans1+=k->sum1;
ans2+=k->sum2;
ans3+=k->sum3;
return;
}
if(k->flag) pushdown(k);
if(L<=k->mid) query(k->ch[0],l,k->mid,L,R);
if(R>k->mid) query(k->ch[1],k->mid+1,r,L,R);
pushup(k);
}
void plus(typetree *&k,LL l,LL r,LL L,LL R,LL v)
{
if(L<=l&&r<=R)
{
k->flag+=v;
k->sum1+=v*(p1[r]-p1[l-1]);
k->sum2+=v*(p2[r]-p2[l-1]);
k->sum3+=v*(p3[r]-p3[l-1]);
return;
}
if(k->flag) pushdown(k);
if(L<=k->mid) plus(k->ch[0],l,k->mid,L,R,v);
if(R>k->mid) plus(k->ch[1],k->mid+1,r,L,R,v);
pushup(k);
}
};
class type *tree;
int main()
{
for(LL i=1;i<=100000;i++)
{
p1[i]=p1[i-1]+1;
p2[i]=p2[i-1]+i;
p3[i]=p3[i-1]+i*i;
}
read(n);read(m);
tree->build(root,1,n-1);
char opt[5];
for(LL x,y,z;m--;)
{
scanf("%s",opt+1);
if(opt[1]==‘C‘)
{
read(x);read(y);read(z);
tree->plus(root,1,n-1,x,y-1,z);
}
else
{
read(x);read(y);
ans1=ans2=ans3=0;
tree->query(root,1,n-1,x,y-1);
LL fm=((y-x+1)*(y-x))/2;
LL fz=(y-x*y)*ans1+(x+y-1)*ans2-ans3;
LL Gcd=gcd(fm,fz);
printf("%lld/",fz/Gcd);
printf("%lld\n",fm/Gcd);
}
}
return 0;
}