题目大意:中文题目
具体思路:通过两棵线段树来维护,第一棵线段树来维护当前坐标的点的日增长速度(默认每一年的增长速度都是当前年份的增长速度),对于第一棵线段树,肯定会存在多算的情况,那么我们第二棵线段树就维护每一个点的多算的情况就可以了。
举个例子:当前的n只有1,初始值也是1, 三个操作,第一年加一个,第二年加一个,第三年加一个。然后问你第四年的当前的个数。在第二年的时候增长速度还是1,第三年的增加速度就是2,第四年的增长速度就是3。对于第四年的话,第一棵线段树的结果出来的是3,在乘上年份就是3*4=12,这个12指的是四年的产量按照每一年的增长速度都是3计算的,然后我们通过第二棵线段树减去不合法的情况,分别是第二年和第三年多算了,我们再通过12-3-2就能解出正确的答案了。
单拿出一个来看的话
一个的单产量 : 1 1 1 2 2 2 2 3 3 3 3 3 4
会发现
CODE:
#include<iostream>
#include<stack>
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
# define ll long long
# define lson l,m,rt<<1
# define rson m+1,r, rt<<1|1
const int maxn = 2e5+1000;
ll tree1[maxn<<2],tree2[maxn<<2];
ll lazy1[maxn<<2],lazy2[maxn<<2];
ll sto[maxn];
void up(ll rt)
{tree1[rt]=tree1[rt<<1]+tree1[rt<<1|1];tree2[rt]=tree2[rt<<1]+tree2[rt<<1|1];
}
void buildtree(ll l,ll r,ll rt)
{tree1[rt]=tree2[rt]=0;lazy1[rt]=lazy2[rt]=0;if(l==r){scanf("%lld",&tree1[rt]);return ;}ll m=(l+r)>>1;buildtree(lson);buildtree(rson);up(rt);
}
void down(ll rt,ll l,ll r)
{ll mid=(l+r)>>1;lazy1[rt<<1]+=lazy1[rt];lazy1[rt<<1|1]+=lazy1[rt];tree1[rt<<1]+=lazy1[rt]*(mid-l+1);tree1[rt<<1|1]+=lazy1[rt]*(r-mid);lazy1[rt]=0;lazy2[rt<<1]+=lazy2[rt];lazy2[rt<<1|1]+=lazy2[rt];tree2[rt<<1]+=lazy2[rt]*(mid-l+1);tree2[rt<<1|1]+=lazy2[rt]*(r-mid);lazy2[rt]=0;
}
void update(ll l,ll r,ll rt,ll L,ll R,ll year)
{if(L<=l&&R>=r){tree1[rt]+=(r-l+1);lazy1[rt]+=1;tree2[rt]+=(r-l+1)*year;lazy2[rt]+=year;return ;}down(rt,l,r);ll m=(l+r)>>1;if(L<=m)update(lson,L,R,year);if(R>m)update(rson,L,R,year);up(rt);
}
ll query(ll l,ll r,ll rt,ll L,ll R,ll year)
{if(R<l||L>r)return 0;if(L<=l&&R>=r){return tree1[rt]*year-tree2[rt];}down(rt,l,r);ll m=(l+r)>>1;return query(lson,L,R,year)+query(rson,L,R,year);up(rt);
}
int main()
{
//freopen("data1.out","r",stdin);ll n;while(~scanf("%lld",&n)){buildtree(1,n,1);ll year=0;int m;char str[10];ll st,ed,num=0;scanf("%d",&m);while(m--){scanf("%s %lld %lld",str,&st,&ed);year++;if(str[0]=='Q'){ll ans=query(1,n,1,st,ed,year);sto[++num]=ans;}else{update(1,n,1,st,ed,year);}}for(int i=1; i<=num; i++){if(i==1)printf("%lld",sto[i]);elseprintf(" %lld",sto[i]);}printf("\n");}return 0;
}