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


    简单明了。直接数据结构了。

    算了还是先想想暴力吧。。。

    暴力开根,暴力求和目测30pts....

    或许可以用树状数组维护前缀和??目测满分.....(维护前缀和,用并查集跳过已经是1的点)

    我还是想练练线段树,那就讲讲线段树写法吧

    首先,没有区间加,不用lazy_tag。

    其次,看数据范围,最大的数开方不超过6次就会变成1(其实这个东西对解题没什么帮助233)

    记录一个区间最大值,这样,当它都等于1了,那么区间里其他小于它的数都已经变成1了,

    所有就可以暴力单点改了。

    在开根的时候,对于最大值也要进行开根处理,然后单点改和区间查就一样了。

    代码也比较短:

    坑点:本蒟蒻在写的时候把区间查也写成了单点查(从叶子结点向上合并),导致了40pts(TLE*6)的好成绩。

    l和r顺序不一定对(建议以后都加上一句swap)

    #include<bits/stdc++.h>
    #define lch(x) x<<1
    #define rch(x) x<<1|1
    using namespace std;
    const long long maxn=100010;
    long long a[maxn];
    long long n,m;
    struct tree
    {
        long long sum,s;
        long long l,r;
    }t[maxn<<2];
    void update(long long p)
    {
        t[p].sum=t[lch(p)].sum+t[rch(p)].sum;
        t[p].s=max(t[lch(p)].s,t[rch(p)].s);
    }
    void build(long long l,long long r,long long p)
    {
        t[p].l=l;
        t[p].r=r;
        if(l==r)
        {
            t[p].sum=t[p].s=abs(a[l]);
            return;
        }
        long long mid=l+r>>1;
        build(l,mid,lch(p));
        build(mid+1,r,rch(p));
        update(p);
    }
    void change(long long l,long long r,long long p)
    {
        if(t[p].l==t[p].r)
        {
            t[p].sum=sqrt(t[p].sum);
            t[p].s=sqrt(t[p].s);
            return;
        }
        long long mid=t[p].l+t[p].r>>1;
        if(l<=mid&&t[p].s>1)
        change(l,r,lch(p));
        if(r>mid&&t[p].s>1)
        change(l,r,rch(p));
        update(p);
    }
    long long ask(long long l,long long r,long long p)
    {
        if(l<=t[p].l&&t[p].r<=r)
        {
            return t[p].sum;
        }
        long long mid=t[p].l+t[p].r>>1;
        long long ans=0;
        if(l<=mid)
        ans+=ask(l,r,lch(p));
        if(r>mid)
        ans+=ask(l,r,rch(p));
        return ans;
    }
    int main()
    {
        scanf("%lld",&n);
        for(long long i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        build(1,n,1);
        scanf("%lld",&m);
        while(m--)
        {
            long long flag,x,y;
            scanf("%lld%lld%lld",&flag,&x,&y);
            if(x>y)
            swap(x,y);
            if(flag==0)
            {
                change(x,y,1);
            }
            if(flag==1)
            {
                printf("%lld
    ",ask(x,y,1));
            }
        }
        return 0;
    }

    (完)

  • 相关阅读:
    CI(CodeIgniter)框架介绍
    yii框架
    Jenkins简单使用介绍
    UNITY_INITIALIZE_OUTPUT宏
    UNITY地图寻路及服务器解决方案
    bloom
    Rigidbody中 Angular Drag (角阻力):
    Unity5 Shader Stripping 导致 LightMap 全部丢失的解决方法
    移动端播放视频文件
    UNITY5 为什么Inspector视图中脚本前面的勾选框没了
  • 原文地址:https://www.cnblogs.com/ajmddzp/p/11397643.html
Copyright © 2020-2023  润新知