种瓜得瓜,种豆得豆 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; }