zoukankan      html  css  js  c++  java
  • 洛谷 P4145 上帝造题的七分钟2 / 花神游历各国

    洛谷

    这题就是区间开根号,区间求和。我们可以分块做。

    我们记布尔数组vis[i]表示第i块中元素是否全部为1。

    因为显然当一个块中元素全部为1时,并不需要对它进行根号操作。

    我们每个块暴力开根号,因为数字最大(2^{31}),所以最多每个数字开几次根号,所以时间复杂度很低。

    记录sum[i]表示第i块的总和,所以我们得到这样的算法:

    当出现修改操作时,我们暴力修改,如果vis[i]为真,则不对该块进行操作。

    而出现查询操作时,直接对正常操作再输出即可。

    代码略丑:

    #include <bits/stdc++.h>
    #define _ putchar('
    ')
    using namespace std;
    typedef int _int;
    #define int long long
    
    const int N=100010;
    bool vis[N];
    int n,m,a[N],len,num;
    int pos[N],sum[N],ll[N],rr[N];
    
    inline void read(int &aa)
    {
        aa=0;char c=getchar();
        for (;c>'9'||c<'0';c=getchar());
        for (;c>='0'&&c<='9';c=getchar())
            aa=(aa<<3)+(aa<<1)+(c^48);
    }
    
    char buffer[N],*S,*T;
    inline char Get_Char()
    {
        if (S==T) {
            T=(S=buffer)+fread(buffer,1,N,stdin);
            if (S==T) return EOF;
        }
        return *S++;
    }
    
    int Get_Int()
    {
        char c;
        int re=0;
        for (c=Get_Char();c<'0'||c>'9';c=Get_Char());
        while (c>='0'&&c<='9')
               re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();
        return re;
    }
    
    void print(int x)
    {
        if (x>9) print(x/10);putchar(x%10^48);
    }
    
    void build()
    {
        len=sqrt(n);
        num=n/len;if (n%len) ++num;
        for (int i=1;i<=num;++i)
            ll[i]=(i-1)*len+1,rr[i]=i*len;
        rr[num]=n;
        for (int i=1;i<=num;++i)
            for (int j=ll[i];j<=rr[i];++j)
                sum[i]+=a[j];
        for (int i=1;i<=n;++i)
            pos[i]=(i-1)/len+1;
    }
    
    int ask(int l,int r)
    {
        int ans=0;
        if (pos[l]==pos[r]) {
            for (int i=l;i<=r;++i)
                ans+=a[i];
            return ans;
        }
        for (int i=l;i<=rr[pos[l]];++i)
            ans+=a[i];
        for (int i=pos[l]+1;i<pos[r];++i)
            ans+=sum[i];
        for (int i=ll[pos[r]];i<=r;++i)
            ans+=a[i];
        return ans;
    }
    
    void change(int l,int r)
    {
        if (pos[l]==pos[r]) {
            if (vis[pos[l]]) return;
            for (int i=l;i<=r;++i) {
                sum[pos[l]]-=a[i];
                a[i]=sqrt(a[i]);
                sum[pos[l]]+=a[i];
            }
            vis[pos[l]]=1;
            for (int i=ll[pos[l]];i<=rr[pos[l]];++i)
                if (a[i]>1) {vis[pos[l]]=0;break;}
            return;
        }
        if (!vis[pos[l]]) {
            for (int i=l;i<=rr[pos[l]];++i) {
                sum[pos[l]]-=a[i];
                a[i]=sqrt(a[i]);
                sum[pos[l]]+=a[i];
            }
            vis[pos[l]]=1;
            for (int i=ll[pos[l]];i<=rr[pos[l]];++i)
                if (a[i]>1) {vis[pos[l]]=0;break;}
        }
        if (!vis[pos[r]]) {
            for (int i=ll[pos[r]];i<=r;++i) {
                sum[pos[r]]-=a[i];
                a[i]=sqrt(a[i]);
                sum[pos[r]]+=a[i];
            }
            vis[pos[r]]=1;
            for (int i=ll[pos[r]];i<=rr[pos[r]];++i)
                if (a[i]>1) {vis[pos[r]]=0;break;}
        }
        for (int i=pos[l]+1;i<pos[r];++i) {
            if (vis[i]) continue;
            for (int j=ll[i];j<=rr[i];++j) {
                sum[i]-=a[j];
                a[j]=sqrt(a[j]);
                sum[i]+=a[j];
            }
            vis[i]=1;
            for (int j=ll[i];j<=rr[i];++j)
                if (a[j]>1) {vis[i]=0;break;}
        }
    }
    
    _int main()
    {
        n=Get_Int();
        for (int i=1;i<=n;++i) a[i]=Get_Int();
        build();
        m=Get_Int();
        int opt,l,r;
        while (m--) {
            opt=Get_Int(),l=Get_Int(),r=Get_Int();
            if (l>r) swap(l,r);
            if (opt) print(ask(l,r)),_;
            else change(l,r);
        }
        return 0;
    }
    
  • 相关阅读:
    用于 webpack 打包后方便修改的配置文件
    antd 中对树形表格中二级元素进行筛选过滤
    layui快速搭建一个后台管理系统
    centos使用shell定时清空缓存
    内存异常原因查询
    Protocol "‘https" not supported or disabled in libcurl
    HTML table标签实现表头固定
    vue 查询某个对象在对象列表的索引位置
    vue 实现页面监听键盘按键 上下左右
    Vue 实现图片监听鼠标滑轮滚动实现图片缩小放大功能
  • 原文地址:https://www.cnblogs.com/fushao2yyj/p/9575507.html
Copyright © 2011-2022 走看看