BZOJ 2752 [HAOI2012]高速公路(road)

线段树裸题

题解

 

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
typedef long long LL;
const int maxn=100005;
using namespace std;
int n,m;

LL sg[maxn<<2],isg[maxn<<2],iisg[maxn<<2],lz[maxn<<2];

#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
 
LL cal(int x,LL l,LL r,LL v) {
    sg[x]+=(r-l+1)*v; 
    isg[x]+=(r-l+1)*(l+r)/2*v; 
    iisg[x]+=(r*(r+1)*(2*r+1)/6-(l-1)*l*(2*l-1)/6)*v; 
    lz[x]+=v;
}

void down(int x,int l,int r) {
    if(!lz[x]) return;
    if(lc) cal(lc,(LL)l,(LL)mid,lz[x]);
    if(rc) cal(rc,(LL)mid+1,(LL)r,lz[x]);
    lz[x]=0;
}

void add(int x,int l,int r,int ql,int qr,LL v) {
    if(l>=ql&&r<=qr) {cal(x,(LL)l,(LL)r,v); return;}
    down(x,l,r);
    if(ql<=mid) add(lc,l,mid,ql,qr,v);
    if(qr>mid) add(rc,mid+1,r,ql,qr,v);
    sg[x]=sg[lc]+sg[rc];
    isg[x]=isg[lc]+isg[rc];
    iisg[x]=iisg[lc]+iisg[rc];
} 

LL sum,isum,iisum;

void qry(int x,int l,int r,int ql,int qr) {
    if(l>=ql&&r<=qr)  {sum+=sg[x]; isum+=isg[x]; iisum+=iisg[x]; return;}  
    down(x,l,r);
    if(ql<=mid) qry(lc,l,mid,ql,qr);
    if(qr>mid) qry(rc,mid+1,r,ql,qr);  
}

LL gcd(LL a,LL b) {
    return !b?a:gcd(b,a%b);
}

int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    scanf("%d%d",&n,&m);
    char op[5];
    LL l,r,v;
    while(m--) {
        scanf("%s%lld%lld",op,&l,&r);
        if(op[0]=='C') {
            scanf("%lld",&v);
            add(1,1,n-1,(int)l,(int)r-1,v);
        }
        else {
            sum=isum=iisum=0;
            qry(1,1,n-1,(int)l,(int)r-1);
            LL fm=(r-l)*(r-l+1)/2LL;
            LL fz=(r+l-1)*isum+(r-l*r)*sum-iisum;
            LL tp=gcd(fm,fz);
            printf("%lld/%lld\n",fz/tp,fm/tp);
        }
    }
    return 0;
}
View Code

 

posted @ 2017-09-29 08:04  啊宸  阅读(129)  评论(0编辑  收藏  举报