分母很显然 分子的话 展开后发现只要维护vi,vi*i, vi*i*i的和就好了
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(char &x) { for (x=nc();x!='Q' && x!='C';x=nc()); } const int N=100005; ll Gcd(ll a,ll b){ if (a<b) return Gcd(b,a); return b?Gcd(b,a%b):a; } inline ll sum(ll l,ll r) { return (l+r)*(r-l+1)/2; } inline ll _sum2(ll n){ return n*(n+1)*(2*n+1)/6; } inline ll sum2(ll l,ll r){ return _sum2(r)-_sum2(l-1); } struct SEGTREE{ struct node{ int l,r; ll s0,s1,s2; friend node operator + (const node &A,const node &B) { if (!A.l) return B; if (!B.l) return A; node ret; ret.l=A.l; ret.r=B.r; ret.s0=A.s0+B.s0; ret.s1=A.s1+B.s1; ret.s2=A.s2+B.s2; return ret; } }T[N*4]; int M,TH; ll H[N*4]; void Build(int n){ for (M=1,TH=0;M<n+2;M<<=1,TH++); for (int i=1;i<=n;i++) { T[M+i].l=T[M+i].r=i; } for (int i=M-1;i;i--) T[i]=T[i<<1]+T[i<<1|1]; } void update(int rt,ll x){ int l=T[rt].l,r=T[rt].r; H[rt]+=x; T[rt].s0+=(r-l+1)*x; T[rt].s1+=sum(l,r)*x; T[rt].s2+=sum2(l,r)*x; } void Pushdown(int rt){ int p; for (int i=TH;i;i--) if (H[p=rt>>i]) { update(p<<1,H[p]); update(p<<1|1,H[p]); H[p]=0; } } void add(int s,int t,ll r){ for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;) { if (~s&1) update(s^1,r); if ( t&1) update(t^1,r); T[s>>=1]=T[s<<1]+T[s<<1|1]; T[t>>=1]=T[t<<1]+T[t<<1|1]; } while (s>>=1) T[s]=T[s<<1]+T[s<<1|1]; } node query(int s,int t){ node lret,rret; lret.l=rret.l=0; for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;s>>=1,t>>=1) { if (~s&1) lret=lret+T[s^1]; if ( t&1) rret=T[t^1]+rret; } return lret+rret; } }Seg; int n; ll iP,iQ,D; int main() { int Q,l,r,ix; char order; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(Q); Seg.Build(n-1); while (Q--) { read(order); read(l); read(r); if (order=='C') { read(ix); Seg.add(l,r-1,ix); } else { SEGTREE::node ret=Seg.query(l,r-1); iP=-ret.s2+(ll)(l+r-1)*ret.s1-(ll)(l-1)*r*ret.s0; iQ=(ll)(r-l+1)*(r-l)/2; D=Gcd(iQ,iP); iP/=D; iQ/=D; printf("%lld/%lld\n",iP,iQ); } } return 0; }