线段树模板
单点修改
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int INF=2147000000; 7 const int maxn=10000; 8 int n; 9 int a[maxn]; 10 int minv[4*maxn]; 11 int ql,qr; 12 int query(int o,int L,int R){ 13 int M=L+(R-L)/2,ans=INF; 14 if(ql<=L&&qr>=R)return minv[o]; 15 if(ql<=M)ans=min(ans,query(2*o,L,M)); 16 if(qr>M)ans=min(ans,query(2*o+1,M+1,R)); 17 return ans; 18 } 19 int p,v;//ÐÞ¸Äa[p]=v 20 void update(int o,int L,int R){ 21 int M=L+(R-L)/2; 22 if(L==R)minv[o]=v; 23 else{ 24 if(p<=M)update(o*2,L,M);else update(2*o+1,M+1,R); 25 minv[o]=min(minv[2*o],minv[2*o+1]); 26 } 27 } 28 int main(){ 29 scanf("%d",&n); 30 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 31 return 0; 32 }
区间修改1
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int maxn=10000; 7 int n; 8 int a[maxn]; 9 int minv[4*maxn],maxv[4*maxn],sumv[4*maxn],addv[4*maxn]; 10 void maintain(int o,int L,int R){ 11 int lc=2*o,rc=2*o+1; 12 sumv[o]=minv[o]=maxv[o]=0; 13 if(R>L){ 14 sumv[o]=sumv[lc]+sumv[rc]; 15 minv[o]=min(minv[lc],minv[rc]); 16 maxv[o]=max(maxv[lc],maxv[rc]); 17 } 18 minv[o]+=addv[o];maxv[o]+=addv[o];sumv[o]+=addv[o]*(R-L+1); 19 } 20 int y1,y2,v; 21 void update(int o,int L,int R){ 22 int lc=2*o,rc=2*o+1; 23 if(y1<=L&&y2>=R){ 24 addv[o]+=v; 25 }else{ 26 int M=L+(R-L)/2; 27 if(y1<=M)update(lc,L,M); 28 if(y2>M)update(rc,M+1,R); 29 } 30 maintain(o,L,R); 31 } 32 int _min,_max,_sum; 33 void query(int o,int L,int R,int add){ 34 if(y1<=L&&y2>=R){ 35 _sum+=sumv[o]+add*(R-L+1); 36 _min=min(_min,minv[o]+add); 37 _max=max(_max,maxv[o]+add); 38 }else{ 39 int M=L+(R-L)/2; 40 if(y1<=M)query(2*o,L,M,add+addv[o]); 41 if(y2>M)query(2*o+1,M+1,R,add+addv[o]); 42 } 43 } 44 int main(){ 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 47 return 0; 48 }
区间修改2
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int maxn=10000; 7 int a[maxn],sumv[maxn],minv[maxn],maxv[maxn],setv[maxn]; 8 int n; 9 int y1,y2,v; 10 void maintain(int o,int L,int R){ 11 int lc=2*o,rc=2*o+1; 12 sumv[o]=minv[o]=maxv[o]=0; 13 if(L<R){ 14 sumv[o]=sumv[lc]+sumv[rc]; 15 minv[o]=min(minv[lc],minv[rc]); 16 maxv[o]=max(maxv[lc],maxv[rc]); 17 } 18 if(setv[o]!=-1){ 19 sumv[o]=setv[o]*(R-L+1); 20 minv[o]=maxv[o]=setv[o]; 21 } 22 } 23 void pushdown(int o){ 24 int lc=o*2,rc=o*2+1; 25 if(setv[o]>=0){ 26 setv[lc]=setv[rc]=setv[o]; 27 setv[o]=-1; 28 } 29 } 30 void update(int o,int L,int R){ 31 int lc=o*2,rc=o*2+1; 32 if(y1<=L&&y2>=R){ 33 setv[o]=v; 34 }else{ 35 pushdown(o); 36 int M=L+(R-L)/2; 37 if(y1<=M)update(lc,L,M);else maintain(lc,L,M); 38 if(y2>M)update(rc,M+1,R);else maintain(rc,M+1,R); 39 } 40 maintain(o,L,R); 41 } 42 int _sum,_max,_min; 43 void query(int o,int L,int R){ 44 if(setv[o]>=0){ 45 _sum+=setv[o]*(min(R,y2)-max(L,y1)+1); 46 _min=min(_min,setv[o]); 47 _max=max(_max,setv[o]); 48 }else if(y1<=L&&y2>=R){ 49 _sum+=sumv[o]; 50 _min=min(_min,minv[o]); 51 _max=max(_max,maxv[o]); 52 }else{ 53 int M=L+(R-L)/2; 54 if(y1<=M)query(o*2,L,M); 55 if(y2>M)query(o*2+1,M+1,R); 56 } 57 } 58 int main(){ 59 scanf("%d",&n); 60 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 61 return 0; 62 }
权值线段树模板
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 const int maxn=100000+100; 8 vector<int>value; 9 int Rank[maxn]; 10 int sumv[4*maxn]; 11 int n; 12 int Findp(int o,int L,int R){ 13 int M=L+(R-L)/2; 14 if(L==R)return L; 15 if(sumv[2*o+1]){ 16 return Findp(2*o+1,M+1,R); 17 } 18 return Findp(2*o,L,M); 19 } 20 int pre(int p,int o,int L,int R){ 21 if(R<p){ 22 if(sumv[o])Findp(o,L,R); 23 return 0; 24 } 25 int M=L+(R-L)/2,Re; 26 if(p-1>M&&sumv[2*o+1]&&(Re=pre(p,2*o+1,M+1,R))){ 27 return Re; 28 } 29 return pre(p,2*o,L,M); 30 } 31 int Findn(int o,int L,int R){ 32 if(L==R)return L; 33 int M=L+(R-L)/2; 34 if(sumv[2*o])return Findn(2*o,L,M); 35 else return Findn(2*o+1,M+1,R); 36 } 37 int nex(int p,int o,int L,int R){ 38 if(p<=L){ 39 if(sumv[o])return Findn(o,L,R); 40 return 0; 41 } 42 int M=L+(R-L)/2,Re; 43 if(p+1<=M&&sumv[2*o]&&(Re=nex(p,2*o,L,M))){ 44 return Re; 45 } 46 return nex(p,2*o+1,M+1,R); 47 } 48 void insert(int x,int o,int L,int R,int d){ 49 sumv[o]+=d; 50 if(L==R)return; 51 int M=L+(R-L)/2; 52 if(x<=M)insert(x,2*o,L,M,d); 53 else insert(x,2*o+1,M+1,R,d); 54 } 55 int find(int x,int o,int L,int R){ 56 int ans=0; 57 if(x<=L)return 0; 58 if(R<x)return sumv[o]; 59 int M=L+(R-L)/2; 60 ans+=find(x,2*o,L,M); 61 if(x-1>M)ans+=find(x,2*o+1,M+1,R); 62 return ans; 63 } 64 int kth(int k,int o,int L,int R){ 65 if(L==R)return L; 66 int M=L+(R-L)/2; 67 if(sumv[2*o]>=k)return kth(k,2*o,L,M); 68 else return kth(k-sumv[2*o],2*o+1,M+1,R); 69 } 70 int main(){ 71 scanf("%d",&n); 72 for(int i=1;i<=n;i++){ 73 int opt,x; 74 scanf("%d%d",&opt,&x); 75 if(opt==1){ 76 value.insert(lower_bound(value.begin(),value.end(),x),x); 77 insert(lower_bound(value.begin(),value.end(),x)-value.begin()+1,1,1,n,1); 78 } 79 if(opt==2){ 80 insert(lower_bound(value.begin(),value.end(),x)-value.begin()+1,1,1,n,-1); 81 } 82 if(opt==3){ 83 printf("%d\n",find(lower_bound(value.begin(),value.end(),x)-value.begin()+1,1,1,n)+1); 84 } 85 if(opt==4){ 86 int ans=kth(x,1,1,n); 87 printf("%d\n",value[ans-1]); 88 } 89 if(opt==5){ 90 int ans=pre(lower_bound(value.begin(),value.end(),x)-value.begin()+1,1,1,n); 91 printf("%d\n",value[ans-1]); 92 } 93 if(opt==6){ 94 int ans=nex(lower_bound(value.begin(),value.end(),x)-value.begin()+1,1,1,n); 95 printf("%d\n",value[ans-1]); 96 } 97 } 98 return 0; 99 }