题目描述
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
输入输出样例
4 5 C 1 4 2 C 1 2 -1 Q 1 2 Q 2 4 Q 1 4
1/1 8/3 17/6
说明
所有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
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 ",ans/p,fm/p); 151 } 152 } 153 return 0; 154 }