2018年8月7日暑假训练日记

上午:

HDU 5372 Segment Game(线段树)

覆盖区间数=左端点大于L-右端点大于R

由于区间比较大,所以进行离散化处理

然后树状数组维护一下就可以了

The shortest problem(hdu5373+11的倍数)

结论题:能被11整除的数字,奇数和偶数位之和的差可以被11整除。

HDU 5381 The sum of gcd(莫队+rmq+二分):

由于n比较小先用rmq+二分预处理一下gcd变换的位置

然后莫队处理区间移动就行了

HDU 5377 Root(扩展欧几里得 + 生成元)

小范围暴力+大范围bsgs裸题,因为比较大的质因子只可以有一个

HDU 5386 Cover

逆向思维,在已知结果的前提下看看这个操做是否合法,合法则记录路径并更新对应行或者列为任意颜色即可

HDU 5387 Clock

模拟指针的移动就行了,为了防止除不尽,全部扩大120倍在进行处理

下午:

一看1005计算几何题目有好多人过,找了个假模板搞了两小时,后来发现就是一个公式,肝到怀疑人生。之后线段树维护最大值和lazy标记,最后tle,结果赛后改成维护最小值就过了......分析一下应该和数据的随机性有关系,实际更新次数并不多

 

上午:

一到比赛就发现线段树模板没得用,手敲又种种出错,所以今天打算看看多校的线段树题目顺便来整理几套能用的模板,毕竟线段树是我的专长,老是坑模板有些难受

杭电多校第二场1007 Naive Operations(线段树七十二变)

  之前做的一道线段树多校题目,维护b[i]-a[i],和最小值,然后如果需要更新暴力更新到单点,同时树状数组维护sum,当时我的思路和题解完全相同,又是没有模板不敢敲系列

HDU 4893 2014多校三 线段树

发现越是像线段树的题目越是没有什么胆量写,这里维护标记表示该区间的数是否全部修改为斐波那契数,一个数组表示和这个区间最近的斐波那契数,一个维护与这个值最近的斐波那切数,做一般的区间更新和单点更新即可

HDU 5828 多校第八场 1008 Rikka with Sequence(线段树--数据加强版)

又是一发线段树优化,区间更新+区间求sqrt+区间查询

线段树的时间复杂度真的是个好东西,一开始看的一个题解,分析了半天最后说这个题目我放弃,也是醉了。

细节多点,不过是个线段树优化的好题,lazy+cover数据优化+输入挂可过

标程解法用极差,就是区间最大值和区间最小值,若相同,直接开方,若极差为一,也可以特殊处理。不过更新完需要pushdown一次

hdu6070 二分+线段树 2017多校第四场1004

其实是个0-1的分数规划,用线段树维护一下出现的值就可以了,这里又一次理解了一下0-1规划

下午:

多校hdu5726 线段树+预处理

这里求gcd和l,r相同的区间的个数

很巧妙的利用了线段树的性质,找到了每次gcd的下降的位置,记录达到加速的目的

单点更新,区间查询(地兵布阵):

#include<iostream>

#include<cstring>

#include<cstdio>

#include<cmath>

#include<algorithm>

#define maxn 400010

using namespace std;

struct xtree{

    long long l,r;

    long long sum;

    //long long maxx;

    //long long minn;

    long long mid(){

        return (l+r)/2;

    }

}tree[maxn];

long long a[maxn];

void pushup(long long id){

    tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;

    //tree[id].maxx=max(tree[id*2].maxx,tree[id*2+1].maxx);

    //tree[id].minn=max(tree[id*2].minn,tree[id*2+1].minn);

}

void build(long long id,long long l,long long r){

    tree[id].l=l;

    tree[id].r=r;

    if (l==r){

        tree[id].sum=a[l];

        //tree[id].maxx=tree[id].minn=a[l];

        return ;

    }

    long long mid=tree[id].mid();

    build(id*2,l,mid);

    build(id*2+1,mid+1,r);

    pushup(id);

}

void update(long long id,long long pos,long long val){

    if (tree[id].l==tree[id].r){

        tree[id].sum+=val;

        //tree[id].maxx=tree[id].minn=tree[id].sum;

        return ;

    }

    long long mid=tree[id].mid();

    if (pos<=mid){

        update(id*2,pos,val);

    }

    else {

        update(id*2+1,pos,val);

    }

    pushup(id);

}

long long query(long long id,long long l,long long r){

    if (tree[id].l>=l&&tree[id].r<=r){

        return tree[id].sum;

    }

    long long mid=tree[id].mid();

    if (r<=mid){

        return query(id*2,l,r);

    }

    else if (l>mid){

        return query(id*2+1,l,r);

    }

    else {

        return query(id*2,l,mid)+query(id*2+1,mid+1,r);

    }

}

int main(){

    long long t;

    long long i,j;

    long long n,m,x,y,z;

    scanf("%lld",&t);

    long long cas=0;

    while (t--){

        scanf("%lld",&n);

        for (i=1;i<=n;i++)scanf("%lld",&a[i]);

        build(1,1,n);

        char fun[11];

        printf("Case %lld:\n",++cas);

        while (1){

            scanf("%s",&fun);

            if (fun[0]=='E')break;

            else if (fun[0]=='A'){

                scanf("%lld%lld",&x,&y);

                update(1,x,y);

            }

            else if (fun[0]=='S'){

                scanf("%lld%lld",&x,&y);

                update(1,x,-y);

            }

            else {

                scanf("%lld%lld",&x,&y);

                long long ans=query(1,x,y);

                printf("%lld\n",ans);

            }

        }

    }

}

区间更新,区间查询(Color the ball):

#include<iostream>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<cstdio>

#define maxn 400010

using namespace std;

struct xtree{

    long long l,r;

    long long lazy;

    long long sum;

    long long mid(){

        return (l+r)/2;

    }

}tree[maxn];

long long a[maxn];

void pushup(long long id){

    tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;

}

void pushdown(long long id){

    if (tree[id].lazy){

        tree[id*2].lazy+=tree[id].lazy;

        tree[id*2+1].lazy+=tree[id].lazy;

        long long mid=tree[id].mid();

        tree[id*2].sum+=tree[id].lazy*(mid-tree[id].l+1);

        tree[id*2+1].sum+=tree[id].lazy*(tree[id].r-mid);

        tree[id].lazy=0;

    }

}

void build(long long id,long long l,long long r){

    tree[id].l=l;

    tree[id].r=r;

    tree[id].lazy=0;

    if (l==r){

        tree[id].sum=0;

        //tree[id].sum=a[l];

        return ;

    }

    long long mid=tree[id].mid();

    build(id*2,l,mid);

    build(id*2+1,mid+1,r);

    pushup(id);

}

void update(long long id,long long l,long long r,long long val){

    if (tree[id].l>=l&&tree[id].r<=r){

        tree[id].lazy+=val;

        tree[id].sum+=(tree[id].r-tree[id].l+1)*val;

        return ;

    }

    pushdown(id);

    long long mid=tree[id].mid();

    if (r<=mid){

        update(id*2,l,r,val);

    }

    else if (l>mid){

        update(id*2+1,l,r,val);

    }

    else {

        update(id*2,l,mid,val);

        update(id*2+1,mid+1,r,val);

    }

    pushup(id);

}

long long query(long long id,long long l,long long r){

    if (tree[id].l>=l&&tree[id].r<=r){

        return tree[id].sum;

    }

    pushdown(id);

    long long mid=tree[id].mid();

    if (r<=mid){

        return query(id*2,l,r);

    }

    else if (l>mid){

        return query(id*2+1,l,r);

    }

    else {

        return query(id*2,l,r)+query(id*2+1,l,r);

    }

}

int main(){

    long long n,x,y;

    long long i;

    while (scanf("%lld",&n)!=EOF&&n){

        build(1,1,n);

        for (i=1;i<=n;i++){

            scanf("%lld%lld",&x,&y);

            update(1,x,y,1);

        }

        for (i=1;i<=n;i++){

            printf("%lld%c",query(1,i,i),i==n?'\n':' ');

        }

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值