• [bzoj3038/3211]上帝造题的七分钟2/花神游历各国_线段树


    上帝造题的七分钟2 bzoj-3038

    题目大意:给定一个序列,支持:区间开方;查询区间和。

    注释:$1le nle 10^5$,$1le val[i] le 10^{12}$。

    想法:这题还挺挺有意思的。查询区间和我们可以用前缀和,但是用上去区间修改就不难想到线段树。那么我们思考如何在log的时间之内完成区间开方。直接打lazy显然实现不了,其实我们发现,每一个$10^{12}$之内的数最多只需要开6次方就可以变成1,$10^{12}$开6次根号是1.53993。所以我们对每一个区间用一个mark标记表示这个区间是不是全是1。如果不是的话,我就暴力修改。这样的话每一个数最多会被修改6次,所以总时间复杂度是O(n*a),a是log级别的。

    P.S.:花神那道题卡读入,不加读入优化会T... ...

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define N 100010 
    #define lson pos<<1
    #define rson pos<<1|1
    using namespace std;
    typedef long long ll;
    ll sum[N<<2],a[N];
    int n,m;
    inline void pushup(int pos)
    {
    	sum[pos]=sum[lson]+sum[rson];
    }
    void build(int pos,int l,int r)
    {
        if(l==r)
        {
            sum[pos]=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(lson,l,mid);
        build(rson,mid+1,r);
        pushup(pos);
    }
    void update(int pos,int l,int r,int x,int y)
    {
        if(x>y)swap(x,y);
        if(sum[pos]==r-l+1)return;
        if(l==r)
        {
            sum[pos]=(ll)sqrt(sum[pos]+0.5);
            return;
        }
        int mid=(l+r)>>1;
        if(y<=mid) update(lson,l,mid,x,y);
        else if(x>mid) update(rson,mid+1,r,x,y);
        else update(lson,l,mid,x,y),update(rson,mid+1,r,x,y);
        pushup(pos);
    }
    ll getsum(int pos,int l,int r,int x,int y)
    {
        if(x>y) swap(x,y);
        if(x<=l&&r<=y) return sum[pos];
        int mid=(l+r)>>1;
        if(y<=mid)return getsum(lson,l,mid,x,y);
        if(x>mid)return getsum(rson,mid+1,r,x,y);
        return getsum(lson,l,mid,x,y)+getsum(rson,mid+1,r,x,y);
    }
    void output()
    {
    	printf("Fuck : %lld
    ",sum[1]);
    }
    int main()
    {
        cin >> n ;
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build(1,1,n);
        cin >> m ;
        for(int k,x,y,i=1;i<=m;i++)
        {
            scanf("%d%d%d",&k,&x,&y);
            if(!k) update(1,1,n,x,y);
            else printf("%lld
    ",getsum(1,1,n,x,y));
    		// output();
        }
        return 0;
    }
    

    小结:线段树是很神奇的...qwq

  • 相关阅读:
    PMP工具与技术篇--4.4.1-1 储备分析
    PMP--4.4 规划成本管理--成本管理计划
    PMP--4.3.4-2 进度基准
    PMP工具与技术篇--4.3.4-1 关键路径分析
    PMP--4.3.4-1 项目进度计划
    pip超时问题解决
    BurpSuite插件_sqlipy
    文件上传漏洞
    SSL安全评估工具
    子域名爆破工具
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9291327.html
Copyright © 2020-2023  润新知