BZOJ 2752: [HAOI2012]高速公路(road) 线段树

这个期望显然可以表示成总价值/总方案数.    

然后我们用线段树依次维护 $\sum val[i]$,$\sum val[i]\times i$,$\sum val[i]\times i^2$ 即可. 

code: 

#include <cmath>
#include <cstdio> 
#include <string>
#include <algorithm>      

#define N 100006
#define ll long long 
#define lson now<<1 
#define rson now<<1|1   

using namespace std;   

namespace IO {    

    void setIO(string s) 
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        // freopen(out.c_str(),"w",stdout); 
    }

}; 

ll re2,re3,re4;   

int n,m;       

struct node {  
    int l,r;  
    ll sum[5],tag;           
}s[N<<2];      

void pushup(int now) 
{ 
    for(int i=0;i<5;++i) 
        s[now].sum[i]=s[lson].sum[i]+s[rson].sum[i]; 
}  

void build(int l,int r,int now) 
{  
    s[now].l=l; 
    s[now].r=r;   
    if(l==r) 
    {
        s[now].sum[0]=l;  
        s[now].sum[1]=(ll)l*l;     
        return;    
    }
    int mid=(l+r)>>1;   
    build(l,mid,lson),build(mid+1,r,rson),pushup(now);  
}

void mark(int now,ll d) 
{   
    s[now].sum[2]+=d*s[now].sum[0];      
    s[now].sum[3]+=(s[now].r-s[now].l+1)*d;   
    s[now].sum[4]+=d*s[now].sum[1];    
    s[now].tag+=d;   
}  

void pushdown(int now) 
{ 
    if(s[now].tag) mark(lson,s[now].tag),mark(rson,s[now].tag),s[now].tag=0;   
}  

void update(int l,int r,int now,int L,int R,int v) 
{ 
    if(l>=L&&r<=R) 
    { 
        mark(now,v); 
        return; 
    } 
    int mid=(l+r)>>1;   
    pushdown(now);  
    if(L<=mid)  update(l,mid,lson,L,R,v);   
    if(R>mid)   update(mid+1,r,rson,L,R,v);   
    pushup(now); 
}   

void query(int l,int r,int now,int L,int R) 
{ 
    if(l>=L&&r<=R)  
    {
        re2+=s[now].sum[2]; 
        re3+=s[now].sum[3]; 
        re4+=s[now].sum[4]; 
        return; 
    } 
    int mid=(l+r)>>1;  
    pushdown(now);  
    if(L<=mid)  query(l,mid,lson,L,R); 
    if(R>mid)   query(mid+1,r,rson,L,R);   
}  

int main() 
{ 
    // IO::setIO("input");  
    int i,j;    
    scanf("%d%d",&n,&m),--n;      
    build(1,n,1);    
    for(i=1;i<=m;++i) 
    {
        char op[3];  
        scanf("%s",op); 
        if(op[0]=='C') 
        {  
            int l,r,v; 
            scanf("%d%d%d",&l,&r,&v);    
            --r;      
            update(1,n,1,l,r,v);      
        }  
        else 
        {     
            int l,r; 
            scanf("%d%d",&l,&r); 
            --r;   
            re2=re3=re4=0;       
            query(1,n,1,l,r);  
            ll up=(r+l)*re2+(ll)(r-(ll)r*l-l+1)*re3-re4;      
            ll dw=(ll)(r-l+2)*(r-l+1)/2;
            ll g=__gcd(up,dw); 
            up/=g,dw/=g;  
            printf("%lld/%lld\n",up,dw);   
        }
    }
    return 0; 
}

  

posted @ 2019-12-30 15:36  EM-LGH  阅读(160)  评论(0编辑  收藏  举报