單點操作和區間查詢
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 1e5+5;
int sum[maxn<<2];
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l == r)
{
scanf("%d",&sum[rt]);
return ;
}
int mid = (l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
void update(int p,int v,int l,int r,int rt)
{
if (l == r)
{
sum[rt] += v;//+-*/都行
return ;
}
ll m = (l+r) >> 1;
if (p <= m)
update(p, v, l, m, rt << 1);
else
update(p, v, m+1, r, rt << 1 | 1);
pushup(rt);
}
int query(int l,int r,int L,int R,int rt)
{
if(L >= l && R <= r)
{
return sum[rt];
}
ll mid = (R+L)>>1;
int ans = 0;
if(l<=mid)
{
ans += query(l,r,L,mid,rt<<1);
}
if(r>mid){
ans += query(l,r,mid+1,R,rt<<1|1);
}
pushup(rt);
return ans;
}//單點建樹及區間查詢
int main()
{
int t;int cnt = 1;
scanf("%d",&t);
while(t--)
{
printf("Case %d:\n",cnt);
cnt++;
int n;
scanf("%d",&n);
build(1,n,1);
string s;
while(1)
{
cin>>s;
int h,rr;
if(s == "Query")
{
scanf("%d%d",&h,&rr);
printf("%d\n",query(h,rr,1,n,1));
}
else if(s == "Add")
{
scanf("%d%d",&h,&rr);
update(h,rr,1,n,1);
}
else if(s == "Sub")
{
scanf("%d%d",&h,&rr);
update(h,-rr,1,n,1);
}
else
{
break;
}
}
}
return 0;
}//適合與單點最簡點那種
簡單的區間更新和查詢總數
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
#define rson rt<<1|1
#define lson rt<<1
ll _sum,_min,_max;
const ll MAXN = 1e5+5;
ll st[MAXN<<2],stmin[MAXN<<2],stvis[MAXN<<2],stmax[MAXN<<2];
ll a[MAXN];
void push_up(ll rt)
{
stmax[rt]=max(stmax[lson],stmax[rson]);
stmin[rt]=min(stmin[lson],stmin[rson]);
st[rt]=st[lson]+st[rson];//修改位置
}
void push_down(ll rt,ll sec) //rt標記節點 sec區間
{
stvis[lson]+=stvis[rt];
st[lson]+=stvis[rt]*(sec-(sec>>1));
stmin[lson]+=stvis[rt];
stmax[lson]+=stvis[rt];
stvis[rson]+=stvis[rt];
st[rson]+=stvis[rt]*(sec>>1);
stmin[rson]+=stvis[rt];
stmax[rson]+=stvis[rt];
stvis[rt]=0;
}
void build(ll l,ll r,ll rt)
{
stvis[rt]=0;
if(l==r)
{
stmax[rt]=stmin[rt]=st[rt]=a[l];
return;
}
ll mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
push_up(rt);
}//建樹
void mod_update(int L,int R,int mod,int l,int r,int rt)//區間mod
{
if(stmax[rt]<mod)
return;
if(l==r)
{
st[rt]%=mod;
stmax[rt]=st[rt];
return;
}
int mid=(l+r)>>1;
if(L<=mid)
mod_update(L,R,mod,l,mid,lson);
if(mid<R)
mod_update(L,R,mod,mid+1,r,rson);
push_up(rt);
}
void update(ll L,ll R,ll v,ll l,ll r,ll rt)
{
if(L<=l&&r<=R)
{
stvis[rt]+=v;
st[rt]+=v*(r-l+1);
stmin[rt]+=v;
stmax[rt]+=v;
return;
}
if(stvis[rt])
push_down(rt,r-l+1);
ll mid=(l+r)>>1;
if(L<=mid)
update(L,R,v,l,mid,lson);
if(mid<R)
update(L,R,v,mid+1,r,rson);
push_up(rt);
}//更新區間的值
ll query(ll L,ll R,ll l,ll r,ll rt)
{
if(L<=l&&r<=R)
return st[rt];
if(stvis[rt])
push_down(rt,r-l+1);
ll mid=(l+r)>>1;
ll sum=0;
if(L<=mid)
sum+=query(L,R,l,mid,lson);//修改位置
if(mid<R)
sum+=query(L,R,mid+1,r,rson);//修改位置
return sum;
}//區間查詢總數
int main() {
ll n, m;
scanf("%lld%lld", &n, &m) ;
for(ll i = 1;i <= n;++i)
{
scanf("%lld",&a[i]);
}
build(1,n,1);
while(m--)
{
char tt;
cin>>tt;
ll v1,v2;ll v3;
if(tt == 'C')
{
scanf("%lld%lld%lld", &v1,&v2,&v3);
update(v1,v2,v3,1,n,1);
}
else {
scanf("%lld%lld",&v1,&v2);
printf("%lld\n", query(v1,v2,1,n,1));
}
}
return 0;
}
求區間最值如果單單是這樣可以用rmq
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
#define ll long long
#define rson rt<<1|1
#define lson rt<<1
const ll MAXN = 1e5+5;
using namespace std;
ll st[MAXN<<2],stmin[MAXN<<2],stvis[MAXN<<2],stmax[MAXN<<2];
ll a[MAXN];
void push_up(int rt)
{
stmax[rt]=max(stmax[lson],stmax[rson]);
stmin[rt]=min(stmin[lson],stmin[rson]);
st[rt]=st[lson]+st[rson];//修改位置
}
void build(int l,int r,int rt)
{
if(l==r)
{
stmax[rt]=stmin[rt]=st[rt]=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
push_up(rt);
}
ll query1(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R)
return stmax[rt];
int mid = (l+r)>>1;ll sum = -inf;
if(L <= mid)
sum = max(sum,query1(L,R,l,mid,lson));//修改位置
if(mid < R)
sum = max(sum,query1(L,R,mid+1,r,rson));//修改位置
return sum;
}//查詢區間最大
ll query2(int L,int R,int l,int r,int rt)
{
if(L <= l &&r<=R)
return stmin[rt];
int mid=(l+r)>>1;ll sum = inf;
if(L <= mid)
sum = min(sum,query2(L,R,l,mid,lson));//修改位置
if(mid < R)
sum = min(sum,query2(L,R,mid+1,r,rson));//修改位置
return sum;
}//查詢區間最小
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i = 1;i <= n;++i)
{
scanf("%d",&a[i]);
}
int l,r;
build(1,n,1);
for(int i = 0;i < q;++i)
{
scanf("%d%d",&l,&r);
int g = query1(l,r,1,n,1)-query2(l,r,1,n,1);
printf("%d\n",g);
}
return 0;
}