[HAOI2012]高速公路(road)
线段树
题解:
Code:
#include <iostream>
#include <cstring>
#include <cstdio>
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
using namespace std;
typedef long long LL;
const LL N = 200005;
LL s1,s2,s3;
LL n,m;
LL pre1[N],pre2[N],pre3[N];
struct Node{
LL l,r,mid; LL tag;
LL sum1,sum2,sum3;
} pool[N*4];
void build(LL x,LL l,LL r){
Node &t=pool[x];
t.l=l; t.r=r; t.mid=(l+r)>>1;
t.sum1=t.sum2=t.sum3=0; t.tag=0;
if(l!=r){
build(x*2,t.l,t.mid);
build(x*2+1,t.mid+1,t.r);
}
}
void update(LL x){
Node &t=pool[x];
t.sum1=t.sum2=t.sum3=0;
if(t.l!=t.r){
Node &lch=pool[x*2], &rch=pool[x*2+1];
t.sum1+=lch.sum1+rch.sum1;
t.sum2+=lch.sum2+rch.sum2;
t.sum3+=lch.sum3+rch.sum3;
}
if(t.tag){
t.sum1+=t.tag*(pre1[t.r]-pre1[t.l-1]);
t.sum2+=t.tag*(pre2[t.r]-pre2[t.l-1]);
t.sum3+=t.tag*(pre3[t.r]-pre3[t.l-1]);
}
}
void pushdown(LL x){
if(pool[x].tag){
pool[x*2].tag+=pool[x].tag;
pool[x*2+1].tag+=pool[x].tag;
pool[x].tag=0;
update(x*2); update(x*2+1);
}
}
void add(LL x,LL ql,LL qr,LL d){
Node &t=pool[x];
if(ql<=t.l && t.r<=qr){
t.tag+=d;
}
else{
if(ql<=t.mid) add(x*2,ql,qr,d);
if(qr>t.mid) add(x*2+1,ql,qr,d);
}
update(x);
}
void query(LL x,LL ql,LL qr){
Node &t=pool[x];
if(ql<=t.l && t.r<=qr){ s1+=t.sum1; s2+=t.sum2; s3+=t.sum3; }
else{
pushdown(x);
if(ql<=t.mid) query(x*2,ql,qr);
if(qr>t.mid) query(x*2+1,ql,qr);
}
}
void init(){
for(LL i=1;i<=n;i++){
pre1[i]=pre1[i-1]+1;
pre2[i]=pre2[i-1]+i;
pre3[i]=pre3[i-1]+i*i;
}
}
LL gcd(LL a,LL b){
return b?gcd(b,a%b):a;
}
int main(){
freopen("a.in","r",stdin);
scanf("%lld%lld",&n,&m);
init();
build(1,1,n-1);
char op[5]; LL l,r,d;
for(LL i=1;i<=m;i++){
scanf("%s%lld%lld",op,&l,&r);
if(op[0]=='C'){
scanf("%lld",&d);
add(1,l,r-1,d);
}
else{
s1=s2=s3=0;
query(1,l,r-1);
// D(s1); D(s2); D(s3); E;
LL up = s1*(r-l*r) + s2*(l+r-1) - s3;
LL down = ((r-l+1)*(r-l))>>1;
// D(up); D(down); E;
LL g = gcd(up,down);
up/=g; down/=g;
printf("%lld/%lld\n",up,down);
}
}
}