zoukankan      html  css  js  c++  java
  • 【bzoj3211】花神游历各国

    首先,单点修改求区间和可以用树状数组实现

    因为开平方很耗时间,所以在这个方面可以优化

    我们知道,开平方开几次之后数字就会等于1

    所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字进行开平方,至于这个数组,可以用并查集维护。

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
     
    typedef long long LL;
     
    #define lowbit(x) (x&(-x))
    #define N 100010
     
    int n,m;
    int ask,l,r,t;
     
    int f[N],a[N];
    LL c[N];
     
    inline int getint()
    {
        int x=0,f=1;
        char ch=getchar();
        while (ch>'9' || ch<'0')
        {
            if (ch=='-')
                f=-1;
            ch=getchar();
        }
        while (ch>='0' && ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
     
    inline int find(int x)
    {
        return x==f[x] ? x : f[x]=find(f[x]);
    }
     
    inline void add(int x,int d)
    {
        while (x<=n)
            c[x]+=d,x+=lowbit(x);
    }
     
    inline LL query(int x)
    {
        LL res(0);
        while (x)
            res+=c[x],x-=lowbit(x);
        return res;
    }
     
    int main()
    {
        n=getint();
        for (int i=1;i<=n;i++)
        {
            a[i]=getint();
            f[i]=i;
            add(i,a[i]);
        }
        f[n+1]=n+1;
        m=getint();
        while (m--)
        {
            ask=getint(),l=getint(),r=getint();
            if (ask==1)
                printf("%lld
    ",query(r)-query(l-1));
            else
                for (int i=l;i<=r;add(i,(t=(int)sqrt(a[i]))-a[i]),a[i]=t,f[i]=(a[i]<=1) ? i+1 : i,i=(find(i)==i ? i+1 : f[i]));
        }
        return 0;
    }
    
    

      

  • 相关阅读:
    学习mongodb简单安装、连接数据库、增删改查
    第三方模块glup学习
    npm 借助第三方模块nrm切换淘宝源
    nodemon 学习
    bootstrap和ie浏览器兼容性问题怎么解决?
    所得税
    债务重组
    非货币性资产交换
    政府补助
    收入 费用 和利润
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5761105.html
Copyright © 2011-2022 走看看