rt,写了一个三叉线段树,无法通过 P3374。
#include<bits/stdc++.h>
#define endl '\n'
#define debug(x) cout<<#x<<':'<<x<<endl
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int N=1e6+5;
int n,m;
int a[N];
#define ls p*3-1
#define ms p*3
#define rs p*3+1
struct node{
int l,r;
int sum,tag;
}tree[N*9];
void push_up(int p){
tree[p].sum=tree[ls].sum+tree[ms].sum+tree[rs].sum;
}
void insert(int p,int k){
if(tree[p].l>tree[p].r) return;
if(!k) return;
tree[p].sum+=k*(tree[p].r-tree[p].l+1);
tree[p].tag+=k;
}
void build(int p,int l,int r){
tree[p].l=l,tree[p].r=r;
if(l>r) return;
if(l==r){
tree[p].sum=a[l];
return;
}
int mid1=l+(r-l+1)/3;
int mid2=r-(r-l+1)/3;
build(ls,l,mid1);
build(ms,mid1+1,mid2);
build(rs,mid2+1,r);
push_up(p);
}
void change(int p,int x,int k){
if(tree[p].l>tree[p].r||!tree[p].l) return;
if(tree[p].l==tree[p].r){
tree[p].sum+=k;
return;
}
int mid1=tree[p].l+(tree[p].r-tree[p].l+1)/3;
int mid2=tree[p].r-(tree[p].r-tree[p].l+1)/3;
int res=0;
if(x<=mid1) change(ls,x,k);
else if(x<=mid2) change(ms,x,k);
else change(rs,x,k);
push_up(p);
}
int ask(int p,int l,int r){
if(tree[p].l>tree[p].r||!tree[p].l) return 0;
if(l<=tree[p].l&&tree[p].r<=r){
return tree[p].sum;
}
int mid1=tree[p].l+(tree[p].r-tree[p].l+1)/3;
int mid2=tree[p].r-(tree[p].r-tree[p].l+1)/3;
int res=0;
if(l<=mid1) res+=ask(ls,l,r);
if(l<=mid2) res+=ask(ms,l,r);
if(r>mid2) res+=ask(rs,l,r);
return res;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1,op,l,r;i<=m;i++){
cin>>op>>l>>r;
if(op==1) change(1,l,r);
if(op==2) cout<<ask(1,l,r)<<endl;
}
return 0;
}