假期集训Day 2

数据结构

知识点目录

1 栈

2 队列

3 优先队列(堆)

4 map

5 vector

6 set

7 链表

8 并查集

9 树状数组

10

题目目录

1 树状数组 LGP3374

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
//#define lowbit(i) i&(-i)
using namespace std;
int n,m;
int p[500005],a[500005];
int lowbit(int i){
    return i&(-i);
}
void changex(int num,int h){
    for(int i=num;i<=n;i+=lowbit(i)){
        a[i]+=h;
    }
    return ;
}
int findx(int x){
    int sum=0;
    for(int i=x;i;i-=lowbit(i)){
        sum+=a[i];
    }
    return sum;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&p[i]);
    }
    for(int i=1;i<=n;i++){
        changex(i,p[i]);
    }
    while(m--){
        int b=0,x=0,y=0;
        scanf("%d%d%d",&b,&x,&y);
        if(b==1){
            changex(x,y);
        }
        if(b==2){
            printf("%d\n",findx(y)-findx(x-1));
        }
    }
    return 0;
}

2 树状数组 2 LGP3368

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n,m;
int z[500005],a[500005],p[500005];
int lowbit(int i){
    return i&(-i);
}
void changex(int num,int h){
    for(int i=num;i<=n;i+=lowbit(i)){
        a[i]+=h;
    }
    return ;
}
void addd(int x,int y,int z){
    changex(x,z);
    changex(y+1,-z);
    return ;
}

int findx(int x){
    int sum=0;
    for(int i=x;i;i-=lowbit(i)){
        sum+=a[i];
    }
    return sum;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&p[i]);
    }
    z[1]=p[1];
    for(int i=2;i<=n;i++){
        z[i]=p[i]-p[i-1];
    }
    for(int i=1;i<=n;i++){
        changex(i,z[i]);
    }
    while(m--){
        int b=0,x=0,y=0,z=0;
        scanf("%d",&b);
        if(b==1){
            scanf("%d%d%d",&x,&y,&z);
            addd(x,y,z);
        }
        if(b==2){
            scanf("%d",&x);
            printf("%d\n",findx(x));
        }
    }
    return 0;
}

3 最大数[BZOJ1012][JSOI2008]LGP1198

题解

可以发现一个数如果右面有比他还大的数,那他永远都不可能成为 答案了
那么我们就只需要维护一个单调递减的栈
每次二分查询即可
显然不能使用STL的栈,因为这道题需要我们访问栈内元素

4 树 [JLOI2012] LGP3252

题解

DFS 一遍整颗树
当便利到一个点时将这个点加入队列,同时队头向 后调整,使队列中元素之和 \(<les\) 记录 \(ans\)
当一个点出栈时将队尾删除,同时队头向前调整,使队列中元素之和刚好 \(\leq s\)
显然需要使用双端队列

猜你喜欢

转载自www.cnblogs.com/liuziwen0224/p/jixunday2.html