线段树板子题自用
思路:单点修改,区间查询
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int INF=0xffffff0; const int maxn=1000001; typedef long long ll; struct Node{ ll val; }tree[4*maxn]; ll a[maxn],n,q; inline void update(ll id){ tree[id].val=tree[2*id].val+tree[2*id+1].val; } ll qurey(ll id,ll l,ll r,ll ql,ll qr){//区间查询板子 if(l==ql&&r==qr) return tree[id].val; ll mid=(l+r)/2; if(qr<=mid) return qurey(2*id,l,mid,ql,qr); else if(ql>mid) return qurey(2*id+1,mid+1,r,ql,qr); else{ return qurey(2*id,l,mid,ql,mid)+qurey(2*id+1,mid+1,r,mid+1,qr); } } inline void change(ll id,ll l,ll r,ll pos,ll val){//单点修改板子 if(l==r){ tree[id].val+=val; } else{ ll mid=(l+r)/2; if(pos<=mid) change(id*2,l,mid,pos,val); else change(id*2+1,mid+1,r,pos,val); update(id); } } inline void build(ll id,ll l,ll r){ if(l==r){ tree[id].val=a[l];return; } ll mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); update(id); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); cin>>n>>q; for(ll i=1;i<=n;i++) cin>>a[i]; build(1,1,n); for(ll i=1;i<=q;i++){ ll mod;cin>>mod; if(mod==1){ ll x;ll d;cin>>x>>d; change(1,1,n,x,d); } else{ ll l,r;cin>>l>>r; ll num=qurey(1,1,n,l,r); cout<<num<<"\n"; } } return 0; }
思路:单点修改,区间查询,利用重载运算符统计最小数数量
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int INF=0xffffff0; const int maxn=200001; struct info{ int minv,cnt; }; info operator + (const info &l,const info &r){ info a; a.minv=min(l.minv,r.minv); if(l.minv==r.minv) a.cnt=l.cnt+r.cnt; else if(l.minv<r.minv) a.cnt=l.cnt; else a.cnt=r.cnt; return a; } struct Node{ info val; }tree[4*maxn]; int a[maxn],n,q; inline void update(int id){ tree[id].val=tree[2*id].val+tree[2*id+1].val; } info qurey(int id,int l,int r,int ql,int qr){//区间查询板子 if(l==ql&&r==qr) return tree[id].val; int mid=(l+r)/2; if(qr<=mid) return qurey(2*id,l,mid,ql,qr); else if(ql>mid) return qurey(2*id+1,mid+1,r,ql,qr); else{ return qurey(2*id,l,mid,ql,mid)+qurey(2*id+1,mid+1,r,mid+1,qr); } } inline void change(int id,int l,int r,int pos,int val){//单点修改板子 if(l==r){ tree[id].val={val,1}; } else{ int mid=(l+r)/2; if(pos<=mid) change(id*2,l,mid,pos,val); else change(id*2+1,mid+1,r,pos,val); update(id); } } inline void build(int id,int l,int r){ if(l==r){ tree[id].val={a[l],1};return; } int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); update(id); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); cin>>n>>q; for(int i=1;i<=n;i++) cin>>a[i]; build(1,1,n); for(int i=1;i<=q;i++){ int mod;cin>>mod; if(mod==1){ int x,d;cin>>x>>d; change(1,1,n,x,d); } else{ int l,r;cin>>l>>r; info num=qurey(1,1,n,l,r); cout<<num.minv<<' '<<num.cnt<<"\n"; } } return 0; }