• [Luogu P4145] 上帝造题的七分钟2 / 花神游历各国


    题目链接

    题目简要:我们需要一个能支持区间内每一个数开方以及区间求和的数据结构。

    解题思路:说道区间修改区间查询,第一个想到的当然就是分块线段树。数据范围要用long long。本来我是看到区间这两个字就想着运用一下还不算特别熟的lazy-tag。但是题目是开方嘛。开方不满足结合律,√4+√4≠√8是很显而易见的事情。所以说是不能直接修改sum的。那么只能每个单点修改。

    如何单点修改?第一个思考的是for循环一下然后套单点。但是实际上这样时间复杂度会极度的退化,是会超时的。此时我们发现每次单点change的时候会重复的访问包含目标节点的大区间再到最小的叶节点。实际上修改a[i]与a[i+1]就是左右的兄弟节点并且还有共同的父亲。所以我们还是用区间修改的模式。只不过要到叶节点才改。

    我们按照上面写的做了以后莫约能拿到四十分左右。那么如何优化呢?我们知道260大概就是长整型的极限了。也就是说一个数最多计算60次的平方根就会到达1。并且再开方也就不会变化。换而言之如果一个区间里面全是1,即sum为区间长度,就可以不用处理了。这里题目有说都为正整数,就不用考虑会有0而不好求是否全为1的情况了。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define cm int mid=(l+r)>>1
    #define zc k<<1
    #define yc (k<<1)+1
    #define din l>=z&&r<=y
    #define dout r<z||l>y
    using namespace std;
    long long read(){
        char ch;
        long long res=0,f=1;
        ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            res=res*10+(ch-'0');
            ch=getchar();
        }
        return res*f;
    }
    long long n,m,a[1600005],xds_sum[1600005];
    void build(int k,int l,int r){
        if(l==r){xds_sum[k]=a[l];return;}
        cm;build(zc,l,mid);build(yc,mid+1,r);
        xds_sum[k]=xds_sum[zc]+xds_sum[yc];
    }
    void change(int k,int l,int r,int z,int y){
        if(dout)return;
        if(din&&xds_sum[k]==(r-l+1))return;
        if(din&&l==r){xds_sum[k]=(long long)sqrt(xds_sum[k]);return;}
        cm;change(zc,l,mid,z,y);change(yc,mid+1,r,z,y);
        xds_sum[k]=xds_sum[zc]+xds_sum[yc];
    }
    long long query(int k,int l,int r,int z,int y){
        if(dout)return 0;
        if(din)return xds_sum[k];
        cm;return query(zc,l,mid,z,y)+query(yc,mid+1,r,z,y);
    }
    int main(){
        n=read();
        for(int i=1;i<=n;++i)a[i]=read();
        build(1,1,n);
        m=read();
        for(int i=1;i<=m;++i){
            int order,x,y;
            order=read();x=read();y=read();
            if(x>y)swap(x,y);
            if(order)printf("%lld
    ",query(1,1,n,x,y));
            else change(1,1,n,x,y);
        }
        return 0;
    }
  • 相关阅读:
    springboot~gradle4.7之后的lombok引用方法
    fzu 2107 Hua Rong Dao(状态压缩)
    jquery 按钮效果 正常、移上、按下
    HDU4550+贪心
    谈mvc开发中gzip压缩的应用
    GET方法传递中文参数乱码解决办法
    游戏开发工具之纹理打包器-3.使用GDI+绘图
    处理机调度
    Adroid学习系列-入门(1)
    Drupal 7.23版本升级笔记
  • 原文地址:https://www.cnblogs.com/clockwhite/p/11208665.html
Copyright © 2020-2023  润新知