Vijos 1448校門外的樹(線段樹)
阿新 • • 發佈:2019-01-24
題意:查詢一個區間內被修改的次數。
思路:線段樹單點更新,區間查詢。
利用括號序列的方法,更新區間[a,b]時,點a記錄左括號數,點b記錄右括號數,查詢區間[a,b]時,即為b之前(包括b)的左括號數-a之前的右括號數。
#include <bits/stdc++.h> using namespace std; #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e5+10; int T,n,m; int Left[maxn<<2],Right[maxn<<2]; void Init(){ memset(Left,0,sizeof(Left)); memset(Right,0,sizeof(Right)); } void PushUp(int rt){ Left[rt]=Left[rt<<1]+Left[rt<<1|1]; Right[rt]=Right[rt<<1]+Right[rt<<1|1]; } void Update(int rt,int l,int r,int pos,bool flag){ if(l==r){ if(!flag) Left[rt]++; else Right[rt]++; return ; } int mid=(l+r)>>1; if(pos<=mid) Update(lson,pos,flag); else Update(rson,pos,flag); PushUp(rt); } int Query(int rt,int l,int r,int L,int R,bool flag){ if(L<=l&&r<=R){ if(!flag) return Left[rt]; else return Right[rt]; } int mid=(l+r)>>1; int res=0; if(L<=mid) res+=Query(lson,L,R,flag); if(R>mid) res+=Query(rson,L,R,flag); return res; } int main() { #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif while(~scanf("%d%d",&n,&m)){ Init(); int op,a,b; while(m--){ scanf("%d%d%d",&op,&a,&b); if(op==1) { Update(1,1,n,a,false); Update(1,1,n,b,true); } else { int l,r; l=Query(1,1,n,1,b,false); if(a==1) r=0; else r=Query(1,1,n,1,a-1,true); printf("%d\n",l-r); } } } return 0; }