线段树模板

单点修改

 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 }
View Code

区间修改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 }
View Code

区间修改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 }
View Code

 权值线段树模板

 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 }
View Code

 

posted @ 2018-04-13 23:54  蒟蒻LQL  阅读(118)  评论(0编辑  收藏  举报