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;
    }
    
    

      

  • 相关阅读:
    结对编程--黄金分割点游戏
    第一次单元测试,小紧张呢!
    Visual studio 2013 安装的漫长过程
    课后练习题:读程序
    进度条
    “啰嗦”的四则运算
    我与git“美妙”的一天
    结对编程(黄金分割点)
    Visual Studio 2015的安装和简单的测试
    软件工程学习体会
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5761105.html
Copyright © 2011-2022 走看看