codevs 1082 線段樹練習3 (線段樹)
阿新 • • 發佈:2019-03-01
ace des 兩種 ++ math 如果 input 題目 ret
思路:區間修改 區間修改 線段樹模板題 數據範圍有所提升 爆了int 要用long long
代碼:
題目:
題目描述 Description給你N個數,有兩種操作:
1:給區間[a,b]的所有數增加X
2:詢問區間[a,b]的數的和。
輸入描述 Input Description第一行一個正整數n,接下來n行n個整數,
再接下來一個正整數Q,每行表示操作的個數,
如果第一個數是1,後接3個正整數,
表示在區間[a,b]內每個數增加X,如果是2,
表示操作2詢問區間[a,b]的和是多少。
pascal選手請不要使用readln讀入
輸出描述 Output Description對於每個詢問輸出一行一個答案
樣例輸入 Sample Input3
1
2
3
2
1 2 3 2
2 2 3
樣例輸出 Sample Output9
數據範圍及提示 Data Size & Hint數據範圍
1<=n<=200000
1<=q<=200000
思路:區間修改 區間修改 線段樹模板題 數據範圍有所提升 爆了int 要用long long
代碼:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int maxn=2e5+10;
int n,m,x,y,v,op;
ll ans;
ll a[maxn];
struct node{
int l,r,lazy;
ll w;
}tree[maxn<<2 ];
void build(int l,int r,int rt){
tree[rt].l=l;
tree[rt].r=r;
if(l==r){
tree[rt].w=a[l];
return;
}
int mid=(l+r)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
tree[rt].w=tree[rt*2].w+tree[rt*2+1].w;
}
void pushdown(int rt){
tree[rt*2].lazy+=tree[rt].lazy;
tree[rt*2+1].lazy+=tree[rt].lazy;
tree[rt*2].w+=1ll*tree[rt].lazy*(tree[rt*2].r-tree[rt*2].l+1);
tree[rt*2+1].w+=1ll*tree[rt].lazy*(tree[rt*2+1].r-tree[rt*2+1].l+1);
tree[rt].lazy=0;
}
void update(int rt){
if(tree[rt].l>=x && tree[rt].r<=y){
tree[rt].w+=1ll*v*(tree[rt].r-tree[rt].l+1);
tree[rt].lazy+=v;
return;
}
if(tree[rt].lazy) pushdown(rt);
int mid=(tree[rt].l+tree[rt].r)/2;
if(x<=mid) update(rt*2);
if(y>mid) update(rt*2+1);
tree[rt].w=tree[rt*2].w+tree[rt*2+1].w;
}
void query(int rt){
if(tree[rt].l>=x && tree[rt].r<=y){
ans+=tree[rt].w;
return;
}
if(tree[rt].lazy) pushdown(rt);
int mid=(tree[rt].l+tree[rt].r)/2;
if(x<=mid) query(rt*2);
if(y>mid) query(rt*2+1);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&x,&y,&v);
update(1);
}
if(op==2){
ans=0;
scanf("%d%d",&x,&y);
query(1);
printf("%lld\n",ans);
}
}
return 0;
}
codevs 1082 線段樹練習3 (線段樹)