Aquabet

Talk is cheap. Show me the code.

0%

线段树模板

  线段树模板带快读快出,忘了从哪位大神抄来的了

  OI时期代码,不保证正确性。

单点修改,区间查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 10000009
#define MOD 10000007
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(long long i=k;i<=n;i++)
#define DREP(i,k,n) for(long long i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
/*相当于:{
long long a;
scanf("%lld",&a);
return a;
}
*/
inline long long read(){
long long x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
/*相当于:{
printf("%lld",a);
}
*/
inline void out(long long x){
if(x<0) putchar('-'),x=-x;
if(x>9) out(x/10);
putchar(x%10+'0');
}
long long n,m,p;
long long input[MAXN];
struct node{
long long l,r;
long long sum,mlz,plz;
}tree[4*MAXN];//线段树记得开四倍空间
inline void build(long long i,long long l,long long r){
tree[i].l=l;
tree[i].r=r;
tree[i].mlz=1;
if(l==r){
tree[i].sum=input[l]%p;
return ;
}
long long mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline void pushdown(long long i){
long long k1=tree[i].mlz,k2=tree[i].plz;
tree[i<<1].sum=(tree[i<<1].sum*k1+k2*(tree[i<<1].r-tree[i<<1].l+1))%p;
tree[i<<1|1].sum=(tree[i<<1|1].sum*k1+k2*(tree[i<<1|1].r-tree[i<<1|1].l+1))%p;
tree[i<<1].mlz=(tree[i<<1].mlz*k1)%p;
tree[i<<1|1].mlz=(tree[i<<1|1].mlz*k1)%p;
tree[i<<1].plz=(tree[i<<1].plz*k1+k2)%p;
tree[i<<1|1].plz=(tree[i<<1|1].plz*k1+k2)%p;
tree[i].plz=0;
tree[i].mlz=1;
return ;
}
inline void mul(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum=(tree[i].sum*k)%p;
tree[i].mlz=(tree[i].mlz*k)%p;
tree[i].plz=(tree[i].plz*k)%p;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l) mul(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) mul(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline void add(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum+=((tree[i].r-tree[i].l+1)*k)%p;
tree[i].plz=(tree[i].plz+k)%p;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l) add(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) add(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline long long search(long long i,long long l,long long r){
if(tree[i].r<l || tree[i].l>r) return 0;
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
pushdown(i);
long long sum=0;
if(tree[i<<1].r>=l) sum+=search(i<<1,l,r)%p;
if(tree[i<<1|1].l<=r) sum+=search(i<<1|1,l,r)%p;
return sum%p;
}
int main(){
in(n); in(m);in(p);
REP(i,1,n) in(input[i]);
build(1,1,n);

REP(i,1,m){
long long fl,a,b,c;
in(fl);
if(fl==1){
in(a);in(b);in(c);
c%=p;
mul(1,a,b,c);
}
if(fl==2){
in(a);in(b);in(c);
c%=p;
add(1,a,b,c);
}
if(fl==3){
in(a);in(b);
printf("%lld\n",search(1,a,b));
}
}
return 0;
}
/*
5 4 1000
1 2 3 4 5
3 1 5
2 1 5 1
1 1 5 2

3 1 5
*/

区间修改,单点查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
int n,m;
int ans;
int input[500010];
struct node
{
int left,right;
int num;
}tree[2000010];
void build(int left,int right,int index)
{
tree[index].num=0;
tree[index].left=left;
tree[index].right=right;
if(left==right)
return ;
int mid=(right+left)/2;
build(left,mid,index*2);
build(mid+1,right,index*2+1);
}
void pls(int index,int l,int r,int k)
{
if(tree[index].left>=l && tree[index].right<=r)
{
tree[index].num+=k;
return ;
}
if(tree[index*2].right>=l)
pls(index*2,l,r,k);
if(tree[index*2+1].left<=r)
pls(index*2+1,l,r,k);
}
void search(int index,int dis)
{
ans+=tree[index].num;
if(tree[index].left==tree[index].right)
return ;
if(dis<=tree[index*2].right)
search(index*2,dis);
if(dis>=tree[index*2+1].left)
search(index*2+1,dis);
}
int main()
{
int n,m;
cin>>n>>m;
build(1,n,1);
for(int i=1;i<=n;i++)
scanf("%d",&input[i]);
for(int i=1;i<=m;i++)
{
int a;
scanf("%d",&a);
if(a==1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
pls(1,x,y,z);
}
if(a==2)
{
ans=0;
int x;
scanf("%d",&x);
search(1,x);
printf("%d\n",ans+input[x]);
}
}
}

区间加法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define init long long
using namespace std;
init n,m;
struct node
{
init l,r,data;
init lt;
}tree[1000010];
init arr[1000010];
void build(init l,init r,init index,init arr[])
{
tree[index].lt=0;
tree[index].l=l;
tree[index].r=r;
if(l==r)
{
tree[index].data=arr[l];
return ;
}
init mid=(l+r)/2;
build(l,mid,index*2,arr);
build(mid+1,r,index*2+1,arr);
tree[index].data=tree[index*2].data+tree[index*2+1].data;
return ;
}
void push_down(init index)
{
if(tree[index].lt!=0)
{
tree[index*2].lt+=tree[index].lt;
tree[index*2+1].lt+=tree[index].lt;
init mid=(tree[index].l+tree[index].r)/2;
tree[index*2].data+=tree[index].lt*(mid-tree[index*2].l+1);
tree[index*2+1].data+=tree[index].lt*(tree[index*2+1].r-mid);
tree[index].lt=0;
}
return ;
}
void up_data(init index,init l,init r,init k)
{
if(tree[index].r<=r && tree[index].l>=l)
{
tree[index].data+=k*(tree[index].r-tree[index].l+1);
tree[index].lt+=k;
return ;
}
push_down(index);
if(tree[index*2].r>=l)
up_data(index*2,l,r,k);
if(tree[index*2+1].l<=r)
up_data(index*2+1,l,r,k);
tree[index].data=tree[index*2].data+tree[index*2+1].data;
return ;
}
init search(init index,init l,init r)
{
if(tree[index].l>=l && tree[index].r<=r)
return tree[index].data;
push_down(index);
init num=0;
if(tree[index*2].r>=l)
num+=search(index*2,l,r);
if(tree[index*2+1].l<=r)
num+=search(index*2+1,l,r);
return num;
}
int main()
{
cin>>n>>m;
for(init i=1;i<=n;i++)
cin>>arr[i];
build(1,n,1,arr);
for(init i=1;i<=m;i++)
{
init f;
cin>>f;
if(f==1)
{
init a,b,c;
cin>>a>>b>>c;
up_data(1,a,b,c);
}
if(f==2)
{
init a,b;
cin>>a>>b;
printf("%lld\n",search(1,a,b));
}
}
}

区间乘法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 10000009
#define MOD 10000007
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(long long i=k;i<=n;i++)
#define DREP(i,k,n) for(long long i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
inline long long read(){
long long x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
inline void out(long long x){
if(x<0) putchar('-'),x=-x;
if(x>9) out(x/10);
putchar(x%10+'0');
}
long long n,m,p;
long long input[MAXN];
struct node{
long long l,r;
long long sum,mlz,plz;
}tree[4*MAXN];
inline void build(long long i,long long l,long long r){
tree[i].l=l;
tree[i].r=r;
tree[i].mlz=1;
if(l==r){
tree[i].sum=input[l]%p;
return ;
}
long long mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline void pushdown(long long i){
long long k1=tree[i].mlz,k2=tree[i].plz;
tree[i<<1].sum=(tree[i<<1].sum*k1+k2*(tree[i<<1].r-tree[i<<1].l+1))%p;
tree[i<<1|1].sum=(tree[i<<1|1].sum*k1+k2*(tree[i<<1|1].r-tree[i<<1|1].l+1))%p;
tree[i<<1].mlz=(tree[i<<1].mlz*k1)%p;
tree[i<<1|1].mlz=(tree[i<<1|1].mlz*k1)%p;
tree[i<<1].plz=(tree[i<<1].plz*k1+k2)%p;
tree[i<<1|1].plz=(tree[i<<1|1].plz*k1+k2)%p;
tree[i].plz=0;
tree[i].mlz=1;
return ;
}
inline void mul(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum=(tree[i].sum*k)%p;
tree[i].mlz=(tree[i].mlz*k)%p;
tree[i].plz=(tree[i].plz*k)%p;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l) mul(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) mul(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline void add(long long i,long long l,long long r,long long k){
if(tree[i].r<l || tree[i].l>r) return ;
if(tree[i].l>=l && tree[i].r<=r){
tree[i].sum+=((tree[i].r-tree[i].l+1)*k)%p;
tree[i].plz=(tree[i].plz+k)%p;
return ;
}
pushdown(i);
if(tree[i<<1].r>=l) add(i<<1,l,r,k);
if(tree[i<<1|1].l<=r) add(i<<1|1,l,r,k);
tree[i].sum=(tree[i<<1].sum+tree[i<<1|1].sum)%p;
return ;
}
inline long long search(long long i,long long l,long long r){
if(tree[i].r<l || tree[i].l>r) return 0;
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
pushdown(i);
long long sum=0;
if(tree[i<<1].r>=l) sum+=search(i<<1,l,r)%p;
if(tree[i<<1|1].l<=r) sum+=search(i<<1|1,l,r)%p;
return sum%p;
}
int main(){
in(n); in(m);in(p);
REP(i,1,n) in(input[i]);
build(1,1,n);

REP(i,1,m){
long long fl,a,b,c;
in(fl);
if(fl==1){
in(a);in(b);in(c);
c%=p;
mul(1,a,b,c);
}
if(fl==2){
in(a);in(b);in(c);
c%=p;
add(1,a,b,c);
}
if(fl==3){
in(a);in(b);
printf("%lld\n",search(1,a,b));
}
}
return 0;
}
/*
5 4 1000
1 2 3 4 5
3 1 5
2 1 5 1
1 1 5 2

3 1 5
*/

区间根号,没有找到合适的模板题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define MAXN 1000010
#define REP(i,k,n) for(int i=k;i<=n;i++)
#define in(a) a=read()
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
f=-1;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return x*f;
}
struct node{
int l,r;
long long lz,sum,maxx,minn;
}tree[MAXN<<2];
int n,m,input[MAXN];
inline void build(int i,int l,int r){
tree[i].l=l;tree[i].r=r;
if(l==r){
tree[i].sum=tree[i].minn=tree[i].maxx=input[l];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
tree[i].maxx=max(tree[i*2].maxx,tree[i*2+1].maxx);
return ;
}
inline void push_down(int i){
if(!tree[i].lz) return ;
long long k=tree[i].lz;
tree[i*2].lz+=k;
tree[i*2+1].lz+=k;
tree[i*2].sum-=(tree[i*2].r-tree[i*2].l+1)*k;
tree[i*2+1].sum-=(tree[i*2+1].r-tree[i*2+1].l+1)*k;
tree[i*2].minn-=k;
tree[i*2+1].minn-=k;
tree[i*2].maxx-=k;
tree[i*2+1].maxx-=k;
tree[i].lz=0;
return ;
}
inline void Sqrt(int i,int l,int r){
if(tree[i].l>=l && tree[i].r<=r && (tree[i].minn-(long long)sqrt(tree[i].minn))==(tree[i].maxx-(long long)sqrt(tree[i].maxx))){
long long u=tree[i].minn-(long long)sqrt(tree[i].minn);
tree[i].lz+=u;
tree[i].sum-=(tree[i].r-tree[i].l+1)*u;
tree[i].minn-=u;
tree[i].maxx-=u;
//cout<<"i"<<i<<" "<<tree[i].sum<<endl;
return ;
}
if(tree[i].r<l || tree[i].l>r) return ;
push_down(i);
if(tree[i*2].r>=l) Sqrt(i*2,l,r);
if(tree[i*2+1].l<=r) Sqrt(i*2+1,l,r);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
tree[i].maxx=max(tree[i*2].maxx,tree[i*2+1].maxx);
//cout<<"i"<<i<<" "<<tree[i].sum<<endl;
return ;
}
inline long long search(int i,int l,int r){
if(tree[i].l>=l && tree[i].r<=r)
return tree[i].sum;
if(tree[i].r<l || tree[i].l>r) return 0;
push_down(i);
long long s=0;
if(tree[i*2].r>=l) s+=search(i*2,l,r);
if(tree[i*2+1].l<=r) s+=search(i*2+1,l,r);
return s;
}
int main(){
in(n);
REP(i,1,n) in(input[i]);
build(1,1,n);
in(m);
int a,b,c;
REP(i,1,m){
in(a);in(b);in(c);
if(a==1)
printf("%lld\n",search(1,b,c));
if(a==2){
Sqrt(1,b,c);
//for(int i=1;i<=7;i++)
// cout<<tree[i].sum<<" ";
// cout<<endl;
}
}
}