线段树相关题目

今天心血来潮复习了一下线段树(被第四个心态搞炸qaq)

前言

  以前写的代码就不改辣,我的风格什么的变来变去的qaq,就不吐槽了。。。

  刷了各种水题,犯了各种各样的蠢,但是还素不太会用qaq

1.codevs 1080 线段树练习

直通

代码酱(≧▽≦)/

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

2.codevs 1081 线段树练习2

直通

代码酱(≧▽≦)/

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

3.codevs 1082 线段树练习3

直通

温馨提示:

  注意要开long long哦~

代码酱(≧▽≦)/

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

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

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

 

 

 

posted @ 2017-11-08 21:46  夜雨声不烦  阅读(281)  评论(0编辑  收藏  举报