• [bzoj3211]:花神游历各国


    来自FallDream的博客,未经允许,请勿转载,谢谢,


    n<=100000 m<=200000 ai<=10^9

    这应该是一个比较经典的问题233 以前就听过了做法 没有实现过。

    其实很简单 线段树维护区间最大值和总和,然后暴力开根号就行了。

    复杂度为什么是对的呢?因为开根号的次数肯定不会太多 10^9在开了5次根之后就一直是1了,也就是对于一个最大值是1的区间,我压根就没必要管它。

    最多开根的次数是5n,每次是log,所以最坏的复杂度是5nlogn+mlogn

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define MN 100000
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0',ch = getchar();
        return x;
    }
    
    struct Tree{int l,r,mx;ll x;}T[MN*4+5];
    int n,a[MN+5],m;
    
    void update(int x)
    {
        int l=x<<1,r=l|1;
        T[x].x=T[l].x+T[r].x;
        T[x].mx=max(T[l].mx,T[r].mx);
    }
    
    void build(int x,int l,int r)
    {
        if((T[x].l=l)==(T[x].r=r)) {T[x].x=T[x].mx=a[l];return;}
        int mid=l+r>>1;
        build(x<<1,l,mid);build(x<<1|1,mid+1,r);
        update(x);
    }
    
    void Mark(int x)
    {
        if(T[x].l==T[x].r) T[x].x=T[x].mx=sqrt(T[x].x);
        else
        {
            if(T[x<<1].mx>1) Mark(x<<1);
            if(T[x<<1|1].mx>1) Mark(x<<1|1);
            update(x);
        }
    }
    
    void Modify(int x,int l,int r)
    {
        if(T[x].l==l&&T[x].r==r) {Mark(x);return;}
        int mid=(T[x].l+T[x].r)>>1;
        if(r<=mid) Modify(x<<1,l,r);
        else if(l>mid) Modify(x<<1|1,l,r);
        else Modify(x<<1,l,mid),Modify(x<<1|1,mid+1,r);
        update(x);
    }
    
    ll Query(int x,int l,int r)
    {
        if(T[x].l==l&&T[x].r==r) return T[x].x;
        int mid=(T[x].l+T[x].r)>>1;
        if(r<=mid) return Query(x<<1,l,r);
        else if(l>mid) return Query(x<<1|1,l,r);
        else return Query(x<<1,l,mid)+Query(x<<1|1,mid+1,r);
    }
    
    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 op=read(),l=read(),r=read();
            if(op==1) printf("%lld
    ",Query(1,l,r));
            else Modify(1,l,r);
        }
        return 0;
    }
  • 相关阅读:
    巧用SQL Server Profiler
    Linq结果直接返回实体对象
    C#(MVC) Word 替换,填充表格,导出并下载PDF文档
    C#匿名类型(Anonymous Type)学习日记
    C#Lambda表达式学习日记
    C#事件(Event)学习日记
    C#委托(Delegate)学习日记
    C#隐私信息(银行账户,身份证号码,名字)中间部分特殊字符替换(*)
    CSS布局模型
    Visual Studio 内置快速生产代码简写集合
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj3211.html
Copyright © 2020-2023  润新知