zoukankan      html  css  js  c++  java
  • HAOI2012 高速公路

    题目链接 戳我

    (ans=sum_{i=l}^r a[i]*(i-l+1)*(r-i+1))
    (ans=sum_{i=l}^r a[i]*(-i^2+(r+l)i+(r-l+1-rl)))

    所以说现在我们需要维护的就是五个量——
    (sum1=sum_{i=l}^r a[i])
    (sum2=sum_{i=l}^r a[i]*i)
    (sum3=sum_{i=l}^r a[i]*i^2)

    但是我们进行更改操作的时候可能比较麻烦,所以我们还需要再在建树的时候预处理出来两个值,然后用他们辅助更新。

    (sum4=sum_{i=l}^r i)
    (sum5=sum_{i=l}^r i^2)

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define MAXN 200010
    using namespace std;
    int n,m;
    long long sum1,sum2,sum3,ans,fn,tmp;
    struct Node{long long l,r,tag,sum[6];}t[MAXN<<2];
    
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    
    inline long long gcd(long long x,long long y){return y==0?x:gcd(y,x%y);}
    
    inline void build(int x,long long l,long long r)
    {
        t[x].l=l,t[x].r=r;
        if(l==r) 
        {
            t[x].sum[4]=l;
            t[x].sum[5]=l*l;
            return;
        }
        int mid=(l+r)>>1;
        build(ls(x),l,mid);
        build(rs(x),mid+1,r);
        t[x].sum[4]=t[ls(x)].sum[4]+t[rs(x)].sum[4];
        t[x].sum[5]=t[ls(x)].sum[5]+t[rs(x)].sum[5];
    }
    
    inline void push_up(int x)
    {
        t[x].sum[1]=t[ls(x)].sum[1]+t[rs(x)].sum[1];
        t[x].sum[2]=t[ls(x)].sum[2]+t[rs(x)].sum[2];
        t[x].sum[3]=t[ls(x)].sum[3]+t[rs(x)].sum[3];
    }
    
    inline void modify(int x,int k)
    {
        t[x].sum[1]+=1ll*(t[x].r-t[x].l+1)*k;
        t[x].sum[2]+=1ll*t[x].sum[4]*k;
        t[x].sum[3]+=1ll*t[x].sum[5]*k;
        t[x].tag+=k;
    }
    
    inline void push_down(int x)
    {
        if(t[x].tag)
        {
            modify(ls(x),t[x].tag);
            modify(rs(x),t[x].tag);
            t[x].tag=0;
        }
    }
    
    inline void update(int x,int ll,int rr,int k)
    {
        int l=t[x].l,r=t[x].r;
        if(ll<=l&&r<=rr)
        {
            modify(x,k);
            return;
        }
        int mid=(l+r)>>1;
        push_down(x);
        if(ll<=mid) update(ls(x),ll,rr,k);
        if(mid<rr) update(rs(x),ll,rr,k);
        push_up(x);
    }
    
    inline void query(int x,int ll,int rr)
    {
        int l=t[x].l,r=t[x].r;
        if(ll<=l&&r<=rr)
        {
            sum1+=t[x].sum[1];
            sum2+=t[x].sum[2];
            sum3+=t[x].sum[3];
            return;
        }
        int mid=(l+r)>>1;
        push_down(x);
        if(ll<=mid) query(ls(x),ll,rr);
        if(mid<rr) query(rs(x),ll,rr);
    }
    
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        freopen("ce.out","w",stdout);
        #endif
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            char op[3];
            int x,y,k;
            scanf("%s",op);
            if(op[0]=='C')
            {
                scanf("%d%d%d",&x,&y,&k);y--;
                update(1,x,y,k);
            }
            else
            {
                sum1=sum2=sum3=0;
                scanf("%d%d",&x,&y);y--;
                query(1,x,y);
                ans=1ll*(y-x+1-1ll*y*x)*sum1+(y+x)*sum2-sum3;
                fn=1ll*(y-x+2)*(y-x+1)/2;
                tmp=gcd(ans,fn);
                ans/=tmp,fn/=tmp;
                printf("%lld/%lld
    ",ans,fn);
            }
        }
    }
    
  • 相关阅读:
    leetcode第14题最长公共前缀
    什么是神经网络
    获取url "?" 后面的字符串
    第一天
    C#和.Ne学习第九天
    C#和.Ne学习第八天
    格式化输出
    C#和.Ne学习
    C#和.Ne学习第七天
    C#类型转换
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10462204.html
Copyright © 2011-2022 走看看