图片:
1.求区间最小值
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=200010;
typedef long long ll;
struct node
{
int minx;
int l,r;
}tr[N*4];
int a[N];
void update(int p)
{
tr[p].minx=min(tr[2*p].minx,tr[2*p+1].minx);
}
void build(int p,int l,int r)
{
if(l==r){
tr[p].minx=a[l];
return ;
}else{
int mid=(l + r) / 2;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
}
update(p);
}
// 当前节点为p,[l,r]为当前区间,修改a[pos]->val
void change(int p,int l,int r,int pos,int val)
{
if(l==r){
tr[p].minx=val;
//a[pos]=val;
}else{
int mid=(l+r)/2;
if(pos<=mid) change(2*p,l,mid,pos,val);
else change(2*p+1,mid+1,r,pos,val);
}
//重要!!
update(p);
}
//[ql,qr]为要查询的区间
int query(int p,int l,int r,int ql,int qr) //时间复杂度O(logn)
{
if(ql==l&&qr==r){
return tr[p].minx;
}else{
int mid=(l + r) / 2;
//[l,mid],[mid+1,r]
if(qr<=mid) return query(2*p,l,mid,ql,qr);
else if(ql>mid) return query(2*p+1,mid+1,r,ql,qr);
else{
//ql<=mid,qr>mid
// [ql,mid],[mid+1,qr]
return minx(query(2*p,l,mid,ql,mid),
query(2*p+1,mid+1,r,mid+1,qr));
}
}
}
2.求区间最小值,同时求最小值出现次数
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=200010;
typedef long long ll;
struct info
{
int minx,mincnt;
};
info operator+(const info &l ,const info &r)
{
info a;
a.minx=min(l.minx,r.minx);
if(l.minx==r.minx)
a.mincnt=l.mincnt+r.mincnt;
else if(l.minx<r.minx)
a.mincnt=l.mincnt;
else a.mincnt=r.mincnt;
return a;
}
struct node
{
info s;
int l,r;
}tr[N*4];
int a[N];
void update(int p)
{
tr[p].s=tr[2*p].s+tr[2*p+1].s;
}
void build(int p,int l,int r)
{
if(l==r){
tr[p].s={a[l],1};
return ;
}else{
int mid=(l + r) / 2;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
}
update(p);
}
// 当前节点为p,[l,r]为当前区间,修改a[pos]->val
void change(int p,int l,int r,int pos,int val)
{
if(l==r){
tr[p].s={val,1};
//a[pos]=val;
}else{
int mid=(l+r)/2;
if(pos<=mid) change(2*p,l,mid,pos,val);
else change(2*p+1,mid+1,r,pos,val);
}
//重要!!
update(p);
}
//[ql,qr]为要查询的区间
info query(int p,int l,int r,int ql,int qr) //时间复杂度O(logn)
{
if(ql==l&&qr==r){
return tr[p].s;
}else{
int mid=(l + r) / 2;
//[l,mid],[mid+1,r]
if(qr<=mid) return query(2*p,l,mid,ql,qr);
else if(ql>mid) return query(2*p+1,mid+1,r,ql,qr);
else{
//ql<=mid,qr>mid
// [ql,mid],[mid+1,qr]
return query(2*p,l,mid,ql,mid)+
query(2*p+1,mid+1,r,mid+1,qr);
}
}
}