线段树相关题目
今天心血来潮复习了一下线段树(被第四个心态搞炸qaq)
前言
以前写的代码就不改辣,我的风格什么的变来变去的qaq,就不吐槽了。。。
刷了各种水题,犯了各种各样的蠢,但是还素不太会用qaq
1.codevs 1080 线段树练习
代码酱(≧▽≦)/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstdio>
#define lson rt<<1
#define rson rt<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int N = 100001;
int n,m,ans;
int x,A,a,b;
struct node {
int l,r,w,f;
} t[N<<2];
inline void build(int rt,int l,int r) {
t[rt].l=l,t[rt].r=r;
if(l==r) {
scanf("%d",&t[rt].w);
return ;
}
build(lson,l,mid);
build(rson,mid+1,r);
t[rt].w=t[lson].w+t[rson].w;
}
inline void down(int rt) {
int l=t[rt].l,r=t[rt].r;
t[lson].f+=t[rt].f;
t[rson].f+=t[rt].f;
t[lson].w+=t[rt].f*(t[lson].r-t[lson].l+1);
t[rson].w+=t[rt].f*(t[rson].r-t[rson].l+1);
t[rt].f=0;
}
inline void add(int rt) {
int l=t[rt].l,r=t[rt].r;
if(l==r) {
t[rt].w+=A;
t[rt].f+=A;
return;
}
if(t[rt].f) down(rt);
if(x<=mid) add(lson);
else add(rson);
t[rt].w=t[lson].w+t[rson].w;
}
inline void ask(int rt) {
int l=t[rt].l,r=t[rt].r;
if(a<=l && r<=b) {
ans+=t[rt].w;
return;
}
if(t[rt].f) down(rt);
if(a<=mid) ask(lson);
if(b>mid) ask(rson);
}
int main() {
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for(int i=1,q; i<=m; i++) {
scanf("%d",&q);
if(q==1) {
scanf("%d%d",&x,&A);
add(1);
} else {
scanf("%d%d",&a,&b);
ask(1);
printf("%d\n",ans);
ans=0;
}
}
return 0;
}
2.codevs 1081 线段树练习2
代码酱(≧▽≦)/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstdio>
#define lson rt<<1
#define rson rt<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int N = 100001;
int n,m,ans;
int a,b,A,x;
struct node {
int l,r,w,f;
} t[N<<2];
inline void build(int rt,int l,int r) {
t[rt].l=l,t[rt].r=r;
if(l==r) {
scanf("%d",&t[rt].w);
return ;
}
build(lson,l,mid);
build(rson,mid+1,r);
t[rt].w=t[lson].w+t[rson].w;
}
inline void down(int rt) {
int l=t[rt].l,r=t[rt].r;
t[lson].f+=t[rt].f;
t[rson].f+=t[rt].f;
t[lson].w+=t[rt].f*(t[lson].r-t[lson].l+1);
t[rson].w+=t[rt].f*(t[rson].r-t[rson].l+1);
t[rt].f=0;
}
inline void add(int rt) {
int l=t[rt].l,r=t[rt].r;
if(a<=l && r<=b) {
t[rt].w+=A*(t[rt].r-t[rt].l+1);
t[rt].f+=A;
return;
}
if(t[rt].f) down(rt);
if(a<=mid) add(lson);
if(b>mid) add(rson);
t[rt].w=t[lson].w+t[rson].w;
}
inline void ask(int rt) {
int l=t[rt].l,r=t[rt].r;
if(l==r) {
ans=t[rt].w;
return;
}
if(t[rt].f) down(rt);
if(x<=mid) ask(lson);
else ask(rson);
}
int main() {
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for(int i=1,q; i<=m; i++) {
scanf("%d",&q);
if(q==1) {
scanf("%d%d%d",&a,&b,&A);
add(1);
} else {
scanf("%d",&x);
ask(1);
printf("%d\n",ans);
ans=0;
}
}
return 0;
}
3.codevs 1082 线段树练习3
温馨提示:
注意要开long long哦~
代码酱(≧▽≦)/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstdio>
#define LL long long
#define lson rt<<1
#define rson rt<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int N = 200001;
int n,m;
int a,b;
LL ans,A;
struct node {
int l,r;
LL w,f;
} t[N<<2];
inline void build(int rt,int l,int r) {
t[rt].l=l,t[rt].r=r;
if(l==r) {
scanf("%lld",&t[rt].w);
return ;
}
build(lson,l,mid);
build(rson,mid+1,r);
t[rt].w=t[lson].w+t[rson].w;
}
inline void down(int rt) {
int l=t[rt].l,r=t[rt].r;
t[lson].f+=t[rt].f;
t[rson].f+=t[rt].f;
t[lson].w+=t[rt].f*(t[lson].r-t[lson].l+1);
t[rson].w+=t[rt].f*(t[rson].r-t[rson].l+1);
t[rt].f=0;
}
inline void add(int rt) {
int l=t[rt].l,r=t[rt].r;
if(a<=l && r<=b) {
t[rt].w+=A*(t[rt].r-t[rt].l+1);
t[rt].f+=A;
return;
}
if(t[rt].f) down(rt);
if(a<=mid) add(lson);
if(b>mid) add(rson);
t[rt].w=t[lson].w+t[rson].w;
}
inline void ask(int rt) {
int l=t[rt].l,r=t[rt].r;
if(a<=l && r<=b) {
ans+=t[rt].w;
return;
}
if(t[rt].f) down(rt);
if(a<=mid) ask(lson);
if(b>mid) ask(rson);
}
int main() {
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for(int i=1,q; i<=m; i++) {
scanf("%d",&q);
if(q==1) {
scanf("%d%d%lld",&a,&b,&A);
add(1);
} else {
scanf("%d%d",&a,&b);
ask(1);
printf("%lld\n",ans);
ans=0;
}
}
return 0;
}
4.codevs 4919 线段树练习4
温馨提示:
①不能够用一个tmp变量进行+减运算qaq,就像下面的
inline void change(int now,int q) {
for(int i=0,tmp; i<Mod; i++) {
tmp=t[now].w[i];
t[now].w[i]=0;
t[now].w[(i+q)%Mod]+=tmp;
}
}
这样会让w[i]除了0号元素之外全部都变成0。。。
②a,b竟然能写反qaq,而且不仅仅是一个函数写反,两个函数都写反了qaq,被蠢哭了qaq
代码酱T^T
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #define lson rt<<1 #define rson rt<<1|1 #define mid ((l+r)>>1) using namespace std; const int Mod = 7; const int N = 100011; int n,m,x; int W[N],tmp[Mod]; struct Tree { int l,r,f; int w[Mod]; //余数 } t[N<<2]; inline void update(int rt) { for(int i=0; i<Mod; i++) t[rt].w[i]=t[lson].w[i]+t[rson].w[i]; } inline void build(int rt,int l,int r) { t[rt].l=l,t[rt].r=r,t[rt].f=0; for(int i=0; i<Mod; i++) t[rt].w[i]=0; if(l==r) { t[rt].w[W[l]%Mod]=1; return; } build(lson,l,mid); build(rson,mid+1,r); update(rt); } /* //不对!!! inline void change(int now,int q) { for(int i=0,tmp; i<Mod; i++) { tmp=t[now].w[i]; t[now].w[i]=0; t[now].w[(i+q)%Mod]+=tmp; } } */ inline void change(int now,int q) { for(int i=0; i<Mod; i++) tmp[(i+q)%Mod]=t[now].w[i]; for(int i=0; i<Mod; i++) t[now].w[i]=tmp[i]; } inline void down(int rt) { int l=t[rt].l,r=t[rt].r; if(l==r) return; t[lson].f+=t[rt].f; t[rson].f+=t[rt].f; change(lson,t[rt].f); change(rson,t[rt].f); t[rt].f =0; } inline int Count(int rt,int a,int b) { if(t[rt].f) down(rt); int l=t[rt].l,r=t[rt].r; if(a==l && r==b) return t[rt].w[0]; if(b<=mid) return Count(lson,a,b); else if(a>mid) return Count(rson,a,b); else return Count(lson,a,mid)+Count(rson,mid+1,b); } inline void Add(int rt,int a,int b) { if(t[rt].f) down(rt); int l=t[rt].l,r=t[rt].r; if(a==l && b==r) { t[rt].f+=x; change(rt,x); return; } if(b<=mid) Add(lson,a,b); else if(a>mid) Add(rson,a,b); else { Add(lson,a,mid); Add(rson,mid+1,b); } update(rt); } int main() { scanf("%d",&n); for(int i=1,q; i<=n; i++) scanf("%d",&q),W[i]=q%Mod; build(1,1,n); scanf("%d",&m); char s[10]; for(int i=1,a,b; i<=m; i++) { cin>>s; if(s[0]=='c') { scanf("%d%d",&a,&b); printf("%d\n",Count(1,a,b)); } else { scanf("%d%d%d",&a,&b,&x); Add(1,a,b); } } return 0; }