种瓜得瓜,种豆得豆 Gym - 102072H(线段树)

建立两个线段树,一个存当前年份的产量,一个存每年多算了多少产量。

最后答案  ans=当前产量*年数-多算的产量

 

ps:对于多算的产量,每年只能在一段连续的区间里加1,也就是说对于每一个点来说如果当前年份+1,那么当前年份多算了当年年份的数量。

一个点 初始为1

产量 1  1  1  2  2  3

年份 1  2  3  4  5  6

多算             3      5

我们从第3年产量+1,所以对于前3年我们每年都多算了1 一共多算了3,第5年同理

  

#include<bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define ls now<<1
#define rs now<<1|1
#define lson l,mid,ls
#define rson mid+1,r,rs

const int maxn=2e5+10;

int tree[maxn*4],T[maxn*4];
int lazy[maxn*4],LL[maxn*4];

void built(int l,int r,int now)
{
    int mid=(l+r)>>1;
    tree[now]=0;
    lazy[now]=0; 
    T[now]=0;
    LL[now]=0;
    if(l==r)
    {
        scanf("%lld",&tree[now]);
        return ;
    }
    built(lson);
    built(rson);
    tree[now]=tree[ls]+tree[rs];
}
void pushdown(int now,int l,int r)
{
    int mid=(l+r)>>1;
    if(lazy[now])
    {
        lazy[rs]+=lazy[now];
        lazy[ls]+=lazy[now];
        tree[ls]+=(mid-l+1)*lazy[now];
        tree[rs]+=(r-mid)*lazy[now];
        lazy[now]=0;
    }
}

void updata(int l,int r,int now,int L,int R,int c)
{
    int mid=(l+r)>>1;
    if(L<=l&&r<=R)
    {
        lazy[now]+=c;
        tree[now]+=c*(r-l+1);
        return ;
    }
    pushdown(now,l,r);
    if(L<=mid) updata(lson,L,R,c);
    if(R>mid)  updata(rson,L,R,c);
    tree[now]=tree[ls]+tree[rs];
}

int query(int l,int r,int now,int L,int R)
{
    int mid=(l+r)>>1;
    if(L<=l&&r<=R)
    {
        return tree[now];
    }
    pushdown(now,l,r);
    int ans=0;
    if(L<=mid) ans+=query(lson,L,R);
    if(R>mid) ans+=query(rson,L,R);
    tree[now]=tree[ls]+tree[rs];
    return ans;
}

void PUSH(int now,int l,int r)
{
    int mid=(l+r)>>1;
    if(LL[now])
    {
        LL[rs]+=LL[now];
        LL[ls]+=LL[now];
        T[ls]+=(mid-l+1)*LL[now];
        T[rs]+=(r-mid)*LL[now];
        LL[now]=0;
    }
}

void up(int l,int r,int now,int L,int R,int c)
{
    int mid=(l+r)>>1;
    if(L<=l&&r<=R)
    {
        LL[now]+=c;
        T[now]+=c*(r-l+1);
        return ;
    }
    PUSH(now,l,r);
    if(L<=mid) up(lson,L,R,c);
    if(R>mid)  up(rson,L,R,c);
    T[now]=T[ls]+T[rs];
}

int q(int l,int r,int now,int L,int R)
{
    int mid=(l+r)>>1;
    if(L<=l&&r<=R)
    {
        return T[now];
    }
    PUSH(now,l,r);
    int ans=0;
    if(L<=mid) ans+=q(lson,L,R);
    if(R>mid) ans+=q(rson,L,R);
    T[now]=T[ls]+T[rs];
    return ans;
}

#undef int
int main()
{
#define int long long
    int n;
    while(scanf("%lld",&n)!=EOF)
    {
        built(1,n,1);
        int m,mub=0;
        scanf("%lld",&m);
        for(int i=1;i<=m;i++)
        {
            char ch;
            int s,t;
            getchar();
            scanf("%c%lld%lld",&ch,&s,&t);
            if(ch=='Q')
            {
                if(mub) printf(" ");
                mub++;
                printf("%lld",query(1,n,1,s,t)*i-q(1,n,1,s,t));
            }
            else
            {
                updata(1,n,1,s,t,1);
                up(1,n,1,s,t,i);
            }
        }
        cout<<"\n";
    }

    return 0;
}

 

posted @ 2019-07-26 14:47  Minun  阅读(184)  评论(0编辑  收藏  举报